Python / PHP / JavaScript中是否有正则表达式的实现支持可变长度的lookbehind-assertion?
/(?<!foo.*)bar/
如何编写具有相同含义但不使用lookbehind-assertion的正则表达式?
这种断言是否有可能在某一天实施?
我认为事情要好得多。
更新
(1)有正则表达式实现已经支持可变长度的lookbehind-assertion。
Python模块regex(非标准re
,但附加regex
模块)支持此类断言(并且还有许多其他很酷的功能)。
>>> import regex
>>> m = regex.search('(?<!foo.*)bar', 'f00bar')
>>> print m.group()
bar
>>> m = regex.search('(?<!foo.*)bar', 'foobar')
>>> print m
None
对我而言,Perl无法做到的正则表达式中有一些东西可以让我感到非常惊讶。可能还有Perl的“增强正则表达式”实现吗?
(谢谢和MRAB +1)。
(2)现代正则表达式中有一个很酷的特征\K
。
这个符号意味着当你进行替换时(从我的观点来看,断言最有趣的用例是替换),所有在\K
之前找到的字符都不能被改变。
s/unchanged-part\Kchanged-part/new-part/x
这几乎就像一个后视断言,但当然不那么灵活。
有关\K
的更多信息:
据我了解,你不能在同一个正则表达式中使用\ K两次。而且你不能说你想要“杀死”你找到的角色。这一直是直到行的开始。
(谢谢和池上+1)。
我的其他问题:
\K
效果的最后一点必须是什么点?regex
的Python。 答案 0 :(得分:40)
大多数情况下,您可以使用\K
来避免可变长度的外观。
s/(?<=foo.*)bar/moo/s;
将是
s/foo.*\Kbar/moo/s;
负面的外观有点棘手。
s/(?<!foo.*)bar/moo/s;
将是
s/^(?:(?!foo).)*\Kbar/moo/s;
因为(?:(?!STRING).)*
是STRING
,[^CHAR]*
是CHAR
。
如果您只是匹配,则可能甚至不需要\K
。
/foo.*bar/s
/^(?:(?!foo).)*bar/s
答案 1 :(得分:10)
答案 2 :(得分:4)
您可以反转字符串AND模式并使用可变长度前瞻
(rab(?!\w*oof)\w*)
以粗体显示:
raboof rab7790oof raboo rabof rab rabo raboooof rabo
根据我所知的原始解决方案:
Jeff'japhy'Pinyan
答案 3 :(得分:2)
您展示的正则表达式会在bar
之前找到foo
之前的任何实例。
一个简单的替代方法是首先匹配字符串foo
,并找到第一次出现的索引。然后搜索bar
,看看是否可以在索引之前找到出现的事件。
如果你想找到bar
之前不是直接的foo
实例,我还可以为它提供一个正则表达式(不使用lookbehind),但它会非常难看。基本上,颠倒/foo/
的意义 - 即/[^f]oo|[^o]o|[^o]|$/
。
答案 4 :(得分:2)
foo.*|(bar)
如果foo
首先在字符串中,那么正则表达式将匹配,但不会有任何组。
否则,它会找到bar
并将其分配给一个组。
因此,您可以使用此正则表达式并在找到的组中查找结果:
>>> import re
>>> m = re.search('foo.*|(bar)', 'f00bar')
>>> if m: print(m.group(1))
bar
>>> m = re.search('foo.*|(bar)', 'foobar')
>>> if m: print(m.group(1))
None
>>> m = re.search('foo.*|(bar)', 'fobas')
>>> if m: print(m.group(1))
>>>