我无法理解如何在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日
答案 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这样的解析库。