我前几天回答了一个问题,即找到两个指定字符之间的字符串。我最终得到了这个相当基本的正则表达式:
>>> import re
>>> def smallest_between_two(a, b, text):
... return re.findall(re.escape(a) + "(.*?)" + re.escape(b), text)
...
>>> smallest_between_two(' ', '(', 'def test()')
['test']
>>> smallest_between_two('[', ']', '[this one][this one too]')
['this one', 'this one too']
>>> smallest_between_two('paste ', '/', '@paste "game_01/01"')
['"game_01']
但是,当我再次查看它时,我意识到当匹配部分包含在另一个匹配中时可能会发生一个常见错误。这是一个例子:
>>> smallest_between_two(' ', '(', 'here is an example()')
['is an example']
我不确定为什么它还没有找到an example
和example
,因为这两者也发生在' '
和'('
之间
我宁愿不这样做以找到其他匹配项:
>>> first_iteration = smallest_between_two(' ', '(', 'here is an example()')
>>> smallest_between_two(' ', '(', first_iteration[0] + '(')
['an example']
答案 0 :(得分:2)
我要解释为什么你这样做的原因。对于重叠匹配,请使用regex
模块的findall
方法和overlapped=True
关键字参数查看the answer already provided by cᴏʟᴅsᴘᴇᴇᴅ。
你的匹配是这样的,因为正则表达式模式中的空格开始,匹配输入中的第一个空间,然后非贪婪量词.*?
匹配该空间之间的最小值和下一个(
。所以,它运作正常。为了更好地理解它,请输入字符串here is an example()another example()
。
现在,为了获得这种情况下的最短匹配,您可以使用零负前瞻,以确保中间没有空格:
(?!.* )(.*?)\(
所以:
In [81]: re.findall(r' (?!.* )(.*?)\(', 'here is an example()')
Out[81]: ['example']
答案 1 :(得分:1)
您正在寻找重叠正则表达式匹配。简单地说,使用python中的默认正则表达式引擎并不容易。
但是,您可以先使用regex
模块(pip install
)。致电regex.findall
并设置overlapped=True
。
import regex
a, b = ' ', '('
text = 'here is an example()'
regex.findall('{}(.*?){}'.format(*map(re.escape, (a, b))), text, overlapped=True)
['is an example', 'an example', 'example']