【问题标题】:Is there a bug in Ruby lookbehind assertions (1.9/2.0)?Ruby 后向断言 (1.9/2.0) 中是否存在错误?
【发布时间】:2013-03-05 21:04:37
【问题描述】:

为什么正则表达式 (?<=fo).* 不匹配 foo(而 (?<=f).* 匹配)?

"foo" =~ /(?<=f).*/m          => 1
"foo" =~ /(?<=fo).*/m         => nil

这似乎只发生在单行模式打开(点匹配换行符);没有它,一切正常:

"foo" =~ /(?<=f).*/           => 1
"foo" =~ /(?<=fo).*/          => 2

在 Ruby 1.9.3 和 2.0.0 上测试。

See it on Rubular

编辑:更多观察:

添加行尾锚不会改变任何内容:

"foo" =~ /(?<=fo).*$/m        => nil

但与惰性量词一起,它“起作用”:

"foo" =~ /(?<=fo).*?$/m       => 2

编辑:还有一些观察:

.+ 与其等效的{1,} 一样工作,但仅在 Ruby 1.9 中(在这种情况下,这似乎是两者之间唯一的行为差异):

"foo" =~ /(?<=fo).+/m         => 2
"foo" =~ /(?<=fo).{1,}/       => 2

在 Ruby 2.0 中:

"foo" =~ /(?<=fo).+/m         => nil
"foo" =~ /(?<=fo).{1,}/m      => nil

.{0,} 被破坏(在 1.9 和 2.0 中):

"foo" =~ /(?<=fo).{0,}/m      => nil

{n,m} 两者都适用:

"foo" =~ /(?<=fo).{0,1}/m     => 2
"foo" =~ /(?<=fo).{0,2}/m     => 2
"foo" =~ /(?<=fo).{0,999}/m   => 2
"foo" =~ /(?<=fo).{1,999}/m   => 2

【问题讨论】:

  • 如果它是一个错误,它在两个不同的正则表达式引擎中(1.9 和 2.0.0 不使用相同的引擎)。
  • 嗯,Ruby 2.0 引擎是 Onigmo,它是 Ruby 1.9 引擎 Oniguruma 的一个分支。因此,如果它真的是一个错误,那么它很可能存在于两个引擎中,但到目前为止都没有被注意到。
  • 好吧,我在 Ruby 错误跟踪器中开了一张票...:bugs.ruby-lang.org/issues/8023
  • @MikeM:Ruby 所说的“多行”在所有其他正则表达式风格中都被称为“单行”。这很令人困惑:)
  • 我认为,如果您从代码块中删除 irb/pry 提示符,并将结果与​​ "foo" =~ /(?&lt;=f).*/m # =&gt; 1 之类的代码放在同一行,那么对许多其他人来说会很有帮助并且更容易阅读.

标签: ruby regex lookbehind


【解决方案1】:

这已被官方归类为as a bug and subsequently fixed,以及另一个关于多行字符串中的\Z 锚点的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多