正则表达式有助于(重叠)

时间:2016-03-16 21:05:18

标签: regex python-3.x

在这里对堆栈溢出做了一些研究之后,我发现可以使用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)

1 个答案:

答案 0 :(得分:0)

finditer永远不会给你重叠的匹配。从文档(强调我的):

  

返回一个迭代器,在字符串中的RE 模式的所有非重叠匹配上产生MatchObject个实例

\W将占用空间,使其无法用于其他匹配。使用前瞻和后视来避免在比赛中使用它们:

exp1 = re.compile("(?<!\w)([0-9]{4}-[0-9]{2}-[0-9]{2})(?!\w)")

(?<!\w)表示“此前没有\w”; (?!\w)是“此后没有\w”。这也使您不必在字符串的开头和结尾放置空格。