带有向后查找和替代的Python正则表达式

7 投票
1 回答
3917 浏览
提问于 2025-04-17 06:39

我想要一个正则表达式,用来找到那些被“HEAD或HEADa”和“HEAD”包裹起来的文本。也就是说,我可能有一段文本,它的开头是“HEAD”或“HEADa”,后面的“HEAD”都是“HEAD”类型的。

  1. HEAD\n\n 文本...文本...HEAD \n\n 文本....文本 HEAD\n\n 文本....文本 .....
  2. HEADa\n\n 文本...文本...HEAD \n\n 文本....文本 HEAD\n\n 文本....文本 .....

我只想提取那些在“HEAD”之间的文本,所以我用了一种包含“向后查找”和“向前查找”的正则表达式来寻找我的“HEAD”。我有以下这个正则表达式:

var = "HEADa", "HEAD"

my_pat = re.compile(r"(?<=^\b"+var[0]+r"|"+var[1]+r"\b) \w*\s\s(.*?)(?=\b"+var[1] +r"\b)",re.DOTALL|re.MULTILINE)

但是,当我尝试执行这个正则表达式时,出现了一个错误提示,告诉我在向后查找的表达式中不能有可变长度。这段正则表达式哪里出错了呢?

1 个回答

14

目前,你的正则表达式的第一部分看起来是这样的:

(?<=^\bHEADa|HEAD\b)

你有两个选择;一个匹配五个字符,另一个匹配四个字符,这就是你出现错误的原因。有些正则表达式的版本虽然说不允许可变长度的回顾,但还是允许这样做,但在Python中不行。你可以把它分成两个回顾,像这样:

(?:(?<=^HEADa\b)|(?<=\bHEAD\b))

...不过其实你可能根本不需要回顾。试试这个:

(?:^HEADa|\bHEAD)\b

后面用 (.*?) 匹配到的内容,仍然可以通过第一个组获取。如果你真的需要分隔符之间的全部文本,可以把它放在第一个组里,其他的组就变成第二个组(或者你可以使用命名组,这样就不用记住数字了)。

一般来说,回顾不应该是你首先考虑的选择。虽然它看起来是解决问题的明显工具,但通常你直接匹配,然后用捕获组提取你想要的部分会更好。这适用于所有的正则表达式版本,不仅仅是Python;虽然在其他版本中你可以用回顾做更多事情,但并不意味着你应该这样做。

顺便说一下,你可能注意到我重新分配了你的单词边界;我觉得这才是你真正想要的。

撰写回答