【发布时间】: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 上测试。
编辑:更多观察:
添加行尾锚不会改变任何内容:
"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" =~ /(?<=f).*/m # => 1之类的代码放在同一行,那么对许多其他人来说会很有帮助并且更容易阅读.
标签: ruby regex lookbehind