regex Python正则表达式模式构建

5uzkadbs  于 2023-02-20  发布在  Python
关注(0)|答案(2)|浏览(121)

我尝试在python中使用可重用的模式组件增量构建下面的正则表达式模式,我希望模式 p 完全匹配 lines 中的文本,但它最终只匹配了第一行。

import re
nbr = re.compile(r'\d+')
string = re.compile(r'(\w+[ \t]+)*(\w+)')
p1 = re.compile(rf"{string.pattern}\s+{nbr.pattern}\s+{string.pattern}")
p2 = re.compile(rf"{nbr.pattern}\s+{string.pattern}")
p1orp2 = re.compile(rf"{p1.pattern}|{p2.pattern}")
p = re.compile(rf"({p1orp2.pattern}\n)+")

lines = (f"aaaa 100284 aaaa\n"
         f"aaaa 365870 bbbb\n"
         f"757166 cccc\n"
         f"111054 cccc\n"
         f"999657 dddd\n"
         f"999 eeee\n"
         f"2955 ffff\n")

match = p.search(lines)
print(match)
print(match.group(0))

下面是打印出来的内容:〈re.匹配对象;范围=(0,14),匹配=“aaa 1284 aaaa '〉aaa 1284 aaaa

pcww981p

pcww981p1#

问题就在这里:

p1orp2 = re.compile(rf"{p1.pattern}|{p2.pattern}")
p = re.compile(rf"({p1orp2.pattern}\n)+")

p中,\n被附加到p1orp2,但这会影响p1orp2|的作用域:添加的\n属于第二个选项,而不是第一个选项。如果您附加的\n已经在p1orp2的定义中,则情况相同:

p1orp2 = re.compile(rf"{p1.pattern}|{p2.pattern}\n")
p = re.compile(rf"({p1orp2.pattern})+")

...而您确实希望p1模式后面也跟\n

p1orp2 = re.compile(rf"{p1.pattern}\n|{p2.pattern}\n")
p = re.compile(rf"({p1orp2.pattern})+")

要使用\n实现这一点,可以在p1orp2的定义中使用括号,这样就限制了|运算符的作用域:

p1orp2 = re.compile(rf"({p1.pattern}|{p2.pattern})")
p = re.compile(rf"({p1orp2.pattern}\n)+")

通过此更改,它将按您的预期工作。

qyuhtwio

qyuhtwio2#

正则表达式模式的问题在于,p1中的捕获组只捕获由空格或制表符分隔的单词序列中的最后一个单词。因此,p1的第二部分只匹配第二行中的最后一个单词,而p1和p2的第一部分不匹配不以单词开头的行。因此,p1或p2不匹配整个输入。
要解决这个问题,你需要修改string来捕获序列中的所有单词,而不仅仅是最后一个。下面是代码的更新版本:

word_sequence = re.compile(r"\w+(?:[ \t]+\w+)*")
            nbr = re.compile(r"\d+")
            p1 = re.compile(rf"{word_sequence.pattern}\s+{nbr.pattern}\s+ 
           {word_sequence.pattern}")
           p2 = re.compile(rf"{nbr.pattern}\s+{word_sequence.pattern}")
           p1orp2 = re.compile(rf"{p1.pattern}|{p2.pattern}")
           p = re.compile(rf"({p1orp2.pattern}\n)+")
    
           lines = (
              f"aaaa 1284 aaaa\n"
              f"aaaa 3650 bbbb\n"
              f"75071 cccc\n"
              f"111872214054 cccc\n"
              f"999 dddd\n"
              f"999 eeee\n"
              f"295255 ffff\n"
                 )
    
         match = p.search(lines)
         print(match)
         print(match.group(0))

相关问题