我在我的正则表达式身体中发现了这些东西,但我不知道我可以用它们做什么。 有人有例子,所以我可以尝试了解它们是如何工作的吗?
(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind
(?>) - atomic group
答案 0 :(得分:661)
给定字符串foobarbarfoo
:
bar(?=bar) finds the 1st bar ("bar" which has "bar" after it)
bar(?!bar) finds the 2nd bar ("bar" which does not have "bar" after it)
(?<=foo)bar finds the 1st bar ("bar" which has "foo" before it)
(?<!foo)bar finds the 2nd bar ("bar" which does not have "foo" before it)
您也可以将它们组合在一起:
(?<=foo)bar(?=bar) finds the 1st bar ("bar" with "foo" before it and "bar" after it)
(?=)
查找表达式A,其中表达式B如下:
A(?=B)
(?!)
找到表达式B不遵循的表达式A:
A(?!B)
(?<=)
查找表达式A前面的表达式A:
(?<=B)A
(?<!)
查找表达式A不在其中的表达式A:
(?<!B)A
(?>)
一个原子组退出一个组,并在该组内的第一个匹配模式后抛弃其他模式(禁用回溯)。
(?>foo|foot)s
应用于foots
将匹配其第一个替代foo
,然后失败,因为s
没有立即跟随,并且因为后退已停用而停止非原子组将允许回溯;如果后续匹配失败,它将回溯并使用替代模式,直到找到整个表达式的匹配或所有可能性都用尽。
(foo|foot)s
的 foots
将:
foo
,然后失败,因为s
没有立即跟随foots
,并回溯到其第二个替代方案; foot
,然后在s
后紧跟foots
成功,然后停止。答案 1 :(得分:203)
Lookarounds是零宽度断言。他们检查正则表达式(朝向当前位置的右侧或左侧 - 基于前方或后方),找到匹配时成功或失败(基于它是正还是负)并丢弃匹配的部分。它们不消耗任何字符 - 跟随它们的正则表达式的匹配(如果有的话)将从相同的光标位置开始。
阅读regular-expression.info了解详情。
语法:
(?=REGEX_1)REGEX_2
仅在REGEX_1匹配时匹配;匹配REGEX_1后,匹配将被丢弃,搜索REGEX_2将从同一位置开始。
示例:
(?=[a-z0-9]{4}$)[a-z]{1,2}[0-9]{2,3}
REGEX_1是[a-z0-9]{4}$
,它匹配四个字母数字字符,后跟行尾
REGEX_2是[a-z]{1,2}[0-9]{2,3}
,它匹配一个或两个字母,后跟两个或三个数字。
REGEX_1确保字符串的长度确实为4,但不消耗任何字符,以便搜索REGEX_2在同一位置开始。现在REGEX_2确保该字符串与其他一些规则匹配。如果没有预见,它将匹配长度为3或5的字符串。
语法:
(?!REGEX_1)REGEX_2
仅当REGEX_1不匹配时才匹配;检查REGEX_1后,搜索REGEX_2的位置相同。
示例:
(?!.*\bFWORD\b)\w{10,30}$
前瞻部分检查字符串中的FWORD
,如果找到则失败。如果找不到FWORD
,则前瞻成功,下一部分验证字符串的长度在10到30之间,并且它只包含单词字符a-zA-Z0-9_
Look-behind类似于前瞻:它只是在当前光标位置后面。像javascript这样的一些正则表达式风格不支持后置断言。大多数支持它的风格(PHP,Python等)要求后视部分具有固定的长度。
答案 2 :(得分:0)
迅速调整环境 如何区分前瞻和后瞻? 和我一起游2分钟:
<xsl:preserve-space elements="Identity price price_date"/>
<xsl:strip-space elements="*"/>
假设
(?=) - positive lookahead
(?<=) - positive lookbehind
现在,我们问B,你在哪里? B有两个解决方案来声明它的位置:
一,B领先A并且有C bebind
二,B领先(前瞻)C和后面(后视)A.
正如我们所看到的,两种解决方案中的背后是相反的 正则表达式是解决方案二。