1

我无法理解如何在 python 中使用命名反向引用。我想查找一月至三月的所有引用及其缩写形式(例如一月、一月、二月、二月等)

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")

应该匹配:

一月

2月23日

3月21日

4

1 回答 1

1

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

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

反向引用的目的是匹配输入字符串中多次出现的相同文本,而不是重复正则表达式本身的一部分。例如,类似(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 之类的解析库。

于 2015-02-02T02:28:02.643 回答