Python - 反向引用命名组

时间:2015-02-02 02:05:26

标签: python regex backreference capturing-group

我无法理解如何在python中使用命名的反向引用。我想找到1月到3月的月份及其缩写形式(例如1月,1月,2月,2月等)。

str = 'Bob Martin brought a car on January 20, 1962. On Feb. the 23rd, Bob sold his car. The 21st of March will be fun.'

re.findall('''
       (?P<Month> (Jan(uary|\.)) | (Feb(ruary|\.)) | (Mar(ch|\.))) # Months
     | (?P=Month)\sthe\s\d{2}(rd|st)
     | [Tt]he\s\d{2}(rd|st)\sof(?P=Month)
'''
str, re.X")

应匹配:

Janurary

二月第23次

3月21日

1 个答案:

答案 0 :(得分:1)

从您的示例中,您似乎尝试使用组作为快捷方式,以避免多次写出一段正则表达式。那就是你想写一个像(?P<expr>this|that)|something then (?P=expr)这样的表达式,让它像你写(this|that)|something then (this|that)一样工作。

但这不是小组的工作方式。捕获组(包括命名组)捕获匹配的内容,而不是表达式本身。在您的示例中,如果输入文本不包含给定月份名称之一,则“月”组将为空。如果 包含一个,那么该组将包含月份名称,但您的模式将不会使用它,因为您正在使用替换,所以如果第一部分(第一行)你的正则表达式匹配,它不会尝试其他部分(第二行和第三行)。

反向引用的目的是匹配 input 字符串中多次出现的相同文本,而不是重复正则表达式本身的一部分。例如,像(a|b) is \1这样的东西将匹配“a is a”或“b is b”,但不匹配“a is b”。因此,此正则表达式与(a|b) is (a|b)不同,后者也匹配“a is b”。

您无法使用反向引用来预定义正则表达式的各个部分。如果你想这样做,你必须定义一个单独的字符串并将其多次连接到模式中。例如,在我的示例中,您可以执行letter = r"(a|b)",然后执行regex = letter + " is " + letter以获取(a|b) is (a|b)

然而,这样做很快就会变得笨拙。正则表达式不是表示具有大量混合和匹配部分的语法的好工具(例如示例中的“月”)。为此,最好使用像parcon这样的解析库。