关于环视:正则表达式前瞻,后观和原子团体

Regex lookahead, lookbehind and atomic groups

我在我的Regex身上发现了这些东西,但我不知道我能用它们做什么。有人有例子让我试着理解他们是如何工作的吗?

1
2
3
4
5
6
(?!) - negative lookahead
(?=) - positive lookahead
(?<=) - positive lookbehind
(?<!) - negative lookbehind

(?>) - atomic group


示例

给定字符串foobarbarfoo

1
2
3
4
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)

您还可以组合它们:

1
(?<=foo)bar(?=bar)    finds the 1st bar ("bar" with"foo" before it and"bar" after it)

号定义展望积极的(?=)

查找表达式A,其中表达式B跟随:

1
A(?=B)

展望消极的(?!)

查找表达式A,其中表达式B不跟随:

1
A(?!B)

。看后面积极的(?<=)

查找表达式A,其中表达式B在前面:

1
(?<=B)A

看后面负的(?

查找表达式A,其中表达式B不在以下位置之前:

1
(?<!B)A

。原子团(?>)

原子组退出组,并在组内第一个匹配的模式之后丢弃可选模式(禁用回溯)。

  • 应用于foots(?>foo|foot)s将与其第一个备选foo相匹配,然后由于s不立即跟随而失败,由于回溯被禁用而停止。

非原子组将允许回溯;如果随后的提前匹配失败,它将回溯并使用替代模式,直到找到整个表达式的匹配或用尽所有可能性。

  • 适用于foots(foo|foot)s将:

  • 匹配其第一个备选方案foo,然后失败,因为s没有立即跟随foots,并返回第二个备选方案;
  • 匹配第二个备选方案foot,然后成功,因为s紧随foots,然后停止。

一些资源

  • http://www.regular-expressions.info/lookaround.html
  • http://www.rexeg.com/regex-lookarounds.html


查找是零宽度断言。它们检查regex(朝向当前位置的右侧或左侧-基于前面或后面),在找到匹配项(基于其为正或负)并丢弃匹配部分时成功或失败。它们不使用任何字符-后面的regex匹配(如果有)将从同一个光标位置开始。

有关详细信息,请阅读regular-expression.info。

  • 正面展望:

语法:

1
(?=REGEX_1)REGEX_2

仅当regex_1匹配时匹配;匹配regex_1后,将放弃匹配,并在相同位置开始搜索regex_2。

例子:

1
(?=[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的字符串。

  • 负面展望

语法:

1
(?!REGEX_1)REGEX_2

仅当regex_1不匹配时匹配;检查regex_1后,搜索regex_2将在同一位置开始。

例子:

1
(?!.*\bFWORD\b)\w{10,30}$

先行部分检查字符串中的FWORD,如果找到,则失败。如果找不到FWORD,则查找成功,下面的部分将验证字符串的长度是否在10到30之间,以及是否只包含单词字符a-zA-Z0-9_

look behind类似于look ahead:它只查看当前光标位置的后面。有些像javascript这样的regex风格不支持查找断言。大多数支持它的风格(php、python等)都要求look-behind部分具有固定的长度。

  • 原子组基本上在令牌匹配后丢弃/忘记组中的后续令牌。检查此页以获取原子组的示例


摸索着快速地环顾四周。如何区分向前看和向后看?和我一起旅游2分钟:

1
2
(?=) - positive lookahead
(?<=) - positive lookbehind

假设

1
    A  B  C #in a line

现在,我们问B,你在哪里?B有两种方法来声明其位置:

一,B领先,C领先第二,B在C前面(向前看),在A后面(向后看)。

正如我们所看到的,在这两个解决方案中,后面和前面是相反的。Regex是解决方案二。