以下是例子:
a = "one two three four five six one three four seven two"
m = re.search("one.*four", a)
我想要的是找到从“one”到“four”的子字符串,其中不含有子字符串“two”。答案应该为:m.group(0) = “one three four”,m.start() = 28,m.end() = 41。 有没有一种方法可以用一行搜索完成这个任务?
(?!...)
:re.findall("one(?!.*two).*four", a)
>>> import re
>>> a = "one two three four five six one three four seven two"
>>> re.findall("one(?!.*two.*four).*four", a)
['one three four']
但是,总有一天你会后悔写复杂的正则表达式。如果我需要解决这个问题,我会这样做:
for m in re.finditer("one.*?four", a):
if "two" not in m.group():
break
这里使用了最小匹配(.*?
),因为正则表达式本身就很棘手。它们可能会让人头痛 :-(
编辑:哈哈!但是如果让字符串变得更加复杂,顶部的混乱正则表达式仍然会失败:
a = "one two three four five six one three four seven two four"
>>> a = 'one two three four five six one three four seven two four'
>>> m = re.search("one([^t]|t(?!wo))*four", a)
>>> m.group()
'one three four'
>>> m.span()
(28, 42)
m.end()
是41,但那是不正确的。one.*?four
带有一个过滤器,将无法处理 "one two one five four"
。必须有一种优雅的解决方案,只捕获 one
、four
和 two
,并取正确的配对。Python 应该是这样的解决方案的好语言,但我不太了解它... - Kobi另一个只有非常简单模式的一行代码
import re
line = "one two three four five six one three four seven two"
print [X for X in [a.split()[1:-1] for a in
re.findall('one.*?four', line, re.DOTALL)] if 'two' not in X]
给我
>>>
[['three']]
^
的多字符版本一样使用(?:(?!two).)*
,对吗? - satoru(?:[^t]|t[^w]|tw[^o])*
,它与不带高级功能(lookahead)的正则表达式兼容。 - Kobilookahead
;) - satorufour
,但这会太麻烦了。让我们像 Satoru 建议的那样继续使用前瞻... - Kobi