正则表达式前瞻,后观和原子团体

时间:2010-06-04 10:56:14

标签: regex lookaround

我在我的正则表达式身体中发现了这些东西,但我不知道我可以用它们做什么。 有人有例子,所以我可以尝试了解它们是如何工作的吗?

(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group

3 个答案:

答案 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将:

    1. 匹配其第一个替代foo,然后失败,因为s没有立即跟随foots,并回溯到其第二个替代方案;
    2. 匹配其第二个替代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等)要求后视部分具有固定的长度。

  • 一旦令牌匹配,原子组基本上会丢弃/忘记组中的后续令牌。请查看此页面,了解atomic groups
  • 的示例

答案 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.

正如我们所看到的,两种解决方案中的背后是相反的 正则表达式是解决方案二。