我在玩正则表达式look ahead时遇到了一些我不理解的东西。
我期望这个正则表达式:
(?=1)x
匹配此字符串:
"x1"
但事实并非如此。在ruby中,代码看起来像:
> "x1".match /(?=1)x/
=> nil
以下是我所期望的:
- 我们从正则表达式解析器在"x"上的光标开始
- 正则表达式引擎在字符串中搜索"1"并获得匹配项。光标仍在"x"上
- regexp引擎搜索"x"并找到它,因为光标没有移动
- 成功!利润
但我显然错了,因为它不匹配。有人能告诉我哪里出了问题吗?
顺便说一句,我注意到,如果lookahead匹配的模式包含我在后续表达式中匹配的字符,那么它就起作用了。即(?=x)x
与x1
完全匹配。我怀疑这是解开谜团的关键,但我就是不明白。:)
前瞻不会使正则表达式索引向前移动,它"站稳脚跟",但它需要在字符串中的当前位置之后存在或不存在某种模式。
当您使用(?=1)x
时,您会告诉正则表达式引擎:
- 下一个字符必须是
1
- 就在这个位置,匹配字符
x
这意味着您要求x
为1
,这永远不是真/永远是假。此正则表达式永远不会匹配任何内容。
以下是regular-expressions.com的另一个例子:
让我们将
q(?=u)i
应用于quit
。展望现在是积极的,后面是另一个标志。同样,q
与q
匹配,u
与u
匹配。同样,必须丢弃前瞻中的匹配,因此引擎从字符串中的i
后退到u
。前瞻性是成功的,因此引擎继续使用i
。但i
不能与u
相匹配。所以这次比赛尝试失败了。所有剩余的尝试也会失败,因为字符串中不再有q
。
另一个必读资源是rexegg.com:上的Lookarounds Stand their Ground
向前看和向后看并不意味着向前看。它们的意思是立即向左或向右看文本。如果你想进一步检查一段字符串,你需要在展望中插入"双筒望远镜",让你找到你想检查的字符串部分——例如
.*
,或者理想情况下,更具体的令牌。
和
不要期望模式
A(?=5)
与字符串AB25
中的A
匹配。许多初学者认为前瞻性声明"在右边的某个地方有一个5
",但事实并非如此。在引擎匹配A
之后,前瞻性声明(?=5)
断言在字符串的当前位置,紧接着的是5
。如果你想检查右边的某个地方(任何地方)是否有5
,你可以使用(?=[^5]*5)
。
我不会给你一篇关于正则表达式断言的长篇论文。
但我要告诉你,永远不要混淆它们是什么,也永远不要忘记如何使用它们。
正则表达式是从左到右处理(解析)的
它们不过是一个花哨的模板。
ASSERTIONS exist BETWEEN characters
在目标文本中,就像它们存在一样
正则表达式中的表达式之间。
They don't exist AT characters
,但介于两者之间。
这意味着你可以很容易地向左或向右看,并应用适当的
断言,即lookAHEAD或lookBEHIND。
这就是你真正需要知道的开始。
您的正则表达式(?=1)x
,例如:
正则表达式表示在字符之间的位置向前看1
,
如果它查找并找到1,则继续下一个表达式
下一个表达式是查找文字x
。
现在,如果下一个字符是1
,那么它就不是x
结果是,正则表达式炸弹的,它永远无法匹配任何东西。