314

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

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

(?>) - atomic group
4

3 回答 3

1235

例子

给定字符串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)

展望负面(?!)

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

A(?!B)

正面看背后(?<=)

查找表达式 B 之前的表达式 A:

(?<=B)A

看负面的背后(?<!)

查找表达式 B 不位于前面的表达式 A:

(?<!B)A

原子团(?>)

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

  • (?>foo|foot)s应用到foots将匹配其第一个替代方案foo,然后失败,因为s没有立即跟进,并停止回溯被禁用

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

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

    1. 匹配它的第一个替代方案foo,然后因为s没有立即跟随而失败foots,并回溯到它的第二个替代方案;
    2. 匹配它的第二个选择foot,然后s立即成功,然后foots停止。

一些资源

在线测试人员

于 2010-06-04T11:06:12.683 回答
234

环视是零宽度断言。他们检查正则表达式(朝向当前位置的右侧或左侧 - 基于前面或后面),在找到匹配时成功或失败(基于它是正还是负)并丢弃匹配的部分。它们不消耗任何字符——它们后面的正则表达式匹配(如果有的话)将从相同的光标位置开始。

阅读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 确保字符串匹配其他一些规则。如果没有前瞻,它将匹配长度为三或五的字符串。

  • 负前瞻

句法:

(?!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 与look-ahead 类似:它只是查看当前光标位置的后面。一些像 javascript 这样的正则表达式风格不支持后视断言。大多数支持它的风格(PHP、Python 等)都要求后视部分具有固定长度。

  • 一旦令牌匹配,原子组基本上丢弃/忘记组中的后续令牌。查看此页面以获取原子组的示例
于 2010-06-04T11:23:21.660 回答
-1

快速环顾四周。
如何区分lookahead和lookbehind?跟我一起来两分钟游览:

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

认为

    A  B  C #in a line

现在,我们问 B,你在哪里?
B 有两种解决方案来声明它的位置:

一,B 前面有 A,后面有 C
二,B 在 C 前面(向前看),在 A 后面(向后看)。

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

于 2018-04-04T15:08:13.503 回答