在这里对堆栈溢出做了一些研究之后,我发现可以使用re.finditer()来获得重叠匹配,但对于我的特定情况,它似乎不起作用。我希望我的正则表达式以YYYY-MM-DD的形式提取由非字母数字(\ W)字符包围的日期。如果两个匹配项之间至少有两个\ W字符,则此工作正常。我的问题是:如何扩充我的表达式,以便它从字符串中提取日期,如下所示: " 2016-02-29 4354-09-21 1900-03-15 1576-05-16"这仅提取2016-02-29和1900-03-15,即使其他有效。 这是代码:
# Find Dates
# dmoj
# author: Aniekan Umoren
# date: 2016-02-15
import re
#input: int N (number of line)
#input: lines containing dates (YYYY-MM-DD) in them
#output: a list of all VALID dates
# turns it into a reegex object which can now use methods like findall
exp1 = re.compile("\W([0-9]{4}-[0-9]{2}-[0-9]{2})\W")
exp2 = re.compile("([0-9]+)-*")
thirty = (4,6,9,11)
N = int(input())
found = []
for i in range(N):
line = input()
matches = exp1.finditer(line)
# returns a tuple of the matched capturing groups
#(or the entire match if there are no capturing groups)
found.extend([str(x.group(1)) for x in matches])
for it in found:
date = [int(x) for x in exp2.findall(it)]
isthirty = False
if (date[1] > 12 or date[2] > 31):
continue
if (date[1] in thirty): isthirty = True
if (isthirty and date[2] <= 30):
print(it)
elif (date[1] == 2):
if (date[0] % 4 == 0 and date[2] <= 29):
print(it)
elif (date[0] % 4 != 0 and date[2] <= 28):
print(it)
elif (not isthirty and date[2] <= 31):
print(it)
答案 0 :(得分:0)
finditer
永远不会给你重叠的匹配。从文档(强调我的):
返回一个迭代器,在字符串中的RE 模式的所有非重叠匹配上产生
MatchObject
个实例
\W
将占用空间,使其无法用于其他匹配。使用前瞻和后视来避免在比赛中使用它们:
exp1 = re.compile("(?<!\w)([0-9]{4}-[0-9]{2}-[0-9]{2})(?!\w)")
(?<!\w)
表示“此前没有\w
”; (?!\w)
是“此后没有\w
”。这也使您不必在字符串的开头和结尾放置空格。