我正在尝试在正则表达式中使用lookbehinds,它似乎不像我预期的那样工作。所以,这不是我的真实用法,但为了简化,我将举一个例子。想象一下,我想在“这是一个例子”的字符串上匹配“example”。所以,根据我对外观的理解,这应该有效:
(?<=this\sis\san\s*?)example
这应该做的是找到“这是一个”,然后是空格字符,最后匹配单词“example”。现在,它不起作用,我不明白为什么,在外观中使用'+'或'*'是不可能的?
我也试过这两个,但它们正常工作,但不能满足我的需求:
(?<=this\sis\san\s)example
this\sis\san\s*?example
我正在使用此网站测试我的正则表达式:http://gskinner.com/RegExr/
答案 0 :(得分:26)
许多正则表达式库只允许在后面的断言中使用严格表达式,如:
(?<=foo|bar|\s,\s)
(每个三个字符)(?<=foobar|\r\n)
(每个具有固定长度的分支)(?<=\s{,4})
(最多四次重复)造成这些限制的原因主要是因为这些库无法向后处理正则表达式或仅处理有限的子集。
另一个原因可能是避免作者构建过于复杂的正则表达式,因为他们有一个所谓的pathological behavior(参见ReDoS),因此很难处理。
另见section about limitations of look-behind assertions上的Regular-Expressions.info。
答案 1 :(得分:11)
嘿,如果你没有使用python变量看看断言,你可以通过转义匹配并使用\K
重新开始来欺骗正则表达式引擎。
这个网站解释得很好.. http://www.phpfreaks.com/blog/pcre-regex-spotlight-k ..
但是,当你有一个你匹配的表达式并且想要使用\ K得到它后面的所有内容时,它会强制它重新开始......
示例:
string = '<a this is a tag> with some information <div this is another tag > LOOK FOR ME </div>'
匹配/(\<a).+?(\<div).+?(\>)\K.+?(?=\<div)/
会导致正则表达式在匹配结束div
标记后重新启动,因此正则表达式不会在结果中包含该标记。 (?=\div)
将使引擎在结束div标签
答案 2 :(得分:4)
Amber说的是真的,但是你可以用另一种方法解决它:一个非捕获括号组
(?<=this\sis\san)(?:\s*)example
这使得固定长度看起来落后,所以它应该有效。
答案 3 :(得分:0)
大多数正则表达式引擎都不支持用于后向断言的可变长度表达式。
答案 4 :(得分:0)
您可以使用子表达式。
(this\sis\san\s*?)(example)
所以要检索组2,“示例”,$2
表示正则表达式,或\2
如果您正在使用格式字符串(如python的re.sub
)