正则表达式中的o修饰符是什么意思?

15

Ruby正则表达式有一些选项(例如ixmo)。例如,i 表示忽略大小写。

o 选项是什么意思?在 ri Regexp 中,它说 o 意味着只进行一次 #{} 插值。但是当我使用以下代码时:

a = 'one'  
b = /#{a}/  
a = 'two'  

b没有改变(它仍然是/one/)。我错过了什么吗?


Translated:

b没有改变(它仍然是/one/)。我错过了什么吗?


你在正则表达式中没有使用 o 标志。你为什么期望它会有任何效果呢? - sawa
如果使用 o 标志表示开启效果,那么我认为在正则表达式中的 #{} 可能会在没有标志的情况下每次执行。 - Liao Pengyu
1
请注意,在 Perl(而不是 Ruby)文档 http://perldoc.perl.org/perlre.html 中指出,“假装优化您的代码,但实际上引入了错误”关于 o 修饰符。因此,在 Perl 中,o 标志似乎具有与 Ruby 不同的含义,并且此外 Perl 标志可能已损坏。 - Rhubbarb
1个回答

22

来自正则表达式的权威指南:

/o会导致特定正则表达式文字中的任何#{...}替换只在第一次评估时执行。否则,每次该文字生成一个Regexp对象时都会执行替换。

我还可以找到这个用法示例:

# avoid interpolating patterns like this if the pattern
# isn't going to change:
pattern = ARGV.shift
ARGF.each do |line|
    print line if line =~ /#{pattern}/
end

# the above creates a new regex each iteration. Instead,
# use the /o modifier so the regex is compiled only once

pattern = ARGV.shift
ARGF.each do |line|
    print line if line =~ /#{pattern}/o
end

所以我猜这更适合编译器,针对执行多次的单行代码。


1
刚才我读了一篇关于“求值策略”的维基百科,现在终于理解了很多。在 Ruby 中,赋值会进行急切求值,所以在 b = /#{a}/ 这段代码执行后,b 被赋值为 /one/,也就是说,“o”标志与此无关。 - Liao Pengyu
此答案已添加到Stack Overflow正则表达式FAQ,位于“修饰符”下。 - aliteralmind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接