Regex lookahead, lookbehind and atomic groups
我在我的Regex身上发现了这些东西,但我不知道我能用它们做什么。有人有例子让我试着理解他们是如何工作的吗?
1 2 3 4 5 6 | (?!) - negative lookahead (?=) - positive lookahead (?<=) - positive lookbehind (?<!) - negative lookbehind (?>) - atomic group |
示例
给定字符串
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是
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}$ |
先行部分检查字符串中的
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是解决方案二。