正面后视vs匹配重置(\ K)正则表达式功能

时间:2016-01-29 19:31:26

标签: php python ruby regex perl

我刚刚了解了Ruby正则表达式中的apparently undocumented \K行为(感谢this answeranubhava)。此功能(可能名为 Keep ?)也存在于PHP,Perl和Python正则表达式中。在其他地方将其描述为" 删除与要返回的匹配项目匹配的内容。"

"abc".match(/ab\Kc/)     # matches "c"

此行为是否与下面使用的正向外观标记相同?

"abc".match(/(?<=ab)c/)  # matches "c"

如果没有,两者会有什么不同之处?

1 个答案:

答案 0 :(得分:7)

使用String#scan方法更容易看出\K(?<=...)之间的区别。

lookbehind是一个零宽度断言,它不消耗字符,并且从当前位置进行测试(向后):

> "abcdefg".scan(/(?<=.)./)
=> ["b", "c", "d", "e", "f", "g"]

&#34;保持&#34; feature \K (不是锚点)定义模式中的位置,其中左边的模式匹配的所有内容都会从匹配结果中删除。但是,\K之前匹配的所有字符消费,它们只是不会出现在结果中:

> "abcdefg".scan(/.\K./)
=> ["b", "d", "f"]

行为与没有\K的行为相同:

> "abcdefg".scan(/../)
=> ["ab", "cd", "ef"]

除了从结果中删除\K之前的字符。

\K的一个有趣用途是模拟可变长度的lookbehind,这在Ruby (PHP和Perl相同)中是不允许的,或者是为了避免创建独特的捕获组。例如,(?<=a.*)f.可以使用\K实现:

> "abcdefg".match(/a.*\Kf./)
=> #<MatchData "fg">

另一种方法是编写/a.*(f.)/,但\K可以避免创建捕获组。

请注意,\K模块中也存在Missing required parameters for [Route: example.destroy] [URI: example/{args}]功能,即使这个功能允许可变长度的后视镜。