【问题标题】:Positive lookbehind vs match reset (\K) regex feature正则后视与匹配重置 (\K) 正则表达式功能
【发布时间】:2016-05-07 15:54:39
【问题描述】:

我刚刚了解了 Ruby 正则表达式中的 apparently undocumented \K 行为(感谢 this answer by anubhava)。此功能(可能命名为 Keep?)也存在于 PHP、Perl 和 Python 正则表达式中。它在其他地方被描述为“将匹配的内容从要返回的匹配中删除。”

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

这种行为是否与下面使用的正向后视标记相同?

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

如果不是,两者有什么不同?

【问题讨论】:

标签: php python ruby regex perl


【解决方案1】:

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

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

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

“保持”功能\K(不是锚)定义了模式中的一个位置,到目前为止,左侧模式匹配的所有内容都将从匹配中删除结果。但是在\K 之前匹配的所有字符都被消耗,它们只是不会出现在结果中:

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

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

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

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

\K 的一个有趣用途是模拟可变长度的后视,这在 Ruby 中是不允许的(PHP 和 Perl 也是如此),或者避免创建唯一的捕获团体。比如(?&lt;=a.*)f.可以使用\K实现:

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

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

请注意,\K 功能也存在于 python regex 模块中,即使这个功能也允许可变长度的后视。

【讨论】:

  • 我不了解 Ruby,但在 Perl 中 \K(?&lt;=...) 快。 /// 一个人通常使用\K 来避免使用捕获组,所以你会提出相反的建议很奇怪。
猜你喜欢
  • 1970-01-01
  • 2022-01-22
  • 2016-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
相关资源
最近更新 更多