查找重叠匹配

时间:2014-07-23 22:28:46

标签: python regex python-3.x

给定一个字符串(来自文本文件的行)我想找到所有这样构建的子串:

  

[[words]]

例如:

  

[[foo [[bar]]

应该同时返回

  

[[foo [[bar]]

  

[[bar]]

另一个例子:

  

[[foo]]和[[bar]]

应该产生

  

[[富]]

  

[[巴]]

我想过像

这样的论坛
\[\[.+\]\]

但它没有正常工作(它匹配太多)。

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

重叠匹配:使用Lookahead

对于延迟重叠,请使用此正则表达式:

(?=(\[\[.?*\]\]))

在Python中:

import re
pattern = r"(?=(\[\[.*?\]\]))"
print(re.findall(pattern, "[[foo [[ bar ]]"))
print(re.findall(pattern, "[[foo]] and [[bar]]"))

输出:

['[[foo [[ bar ]]', '[[ bar ]]']
['[[foo]]', '[[bar]]']

对于“贪婪重叠”,请使用(?=(\[\[.*\]\]))

输出:

['[[foo [[ bar ]]', '[[ bar ]]']
['[[foo]] and [[bar]]', '[[bar]]']

<强>解释

  • 前瞻(?= ... )断言括号内的内容可以匹配(但不匹配,以便我们可以找到重叠的匹配)
  • `([[。*]]周围的括号将匹配的字符串捕获到Group 1
  • \[\[匹配[[
  • .* gredily匹配任何字符
  • .*?中的星形量词由?变为“懒惰”,因此点只匹配所需的字符数以允许下一个标记匹配(最短匹配)。如果没有?,则.*首先匹配整个字符串,然后仅根据需要进行回溯以允许下一个标记匹配(最长匹配)。
  • \]\]匹配]]

<强>参考

答案 1 :(得分:1)

这使用正向前瞻断言来捕获,返回重叠的匹配:

>>> re.findall(r'(?=(\[\[.*?\]\]))', '[[foo [[ bar ]]')
# ['[[foo [[ bar ]]', '[[ bar ]]']

>>> re.findall(r'(?=(\[\[.*?\]\]))', '[[foo]] and [[bar]]')
# ['[[foo]]', '[[bar]]']

注意 ?量词之后的*使您的比赛非贪婪..