0

我正在使用 Ruby1.9.3。我是这个平台的新手。

从我了解到的文档中,我们可以Regexp使用以下内容:

  • %r{pattern}
  • /pattern/

现在,在模式匹配符号、区域细节()等方面styles,上述两者之间有什么区别吗?fast***can use/can't use restrictions***

我找到了一个如下:

irb(main):006:0> s= '2/3'
=> "2/3"
irb(main):008:0> /2\/3/ =~ s
=> 0
irb(main):009:0> %r(2/3) =~ s
=> 0
irb(main):010:0> exit

%r(..)在这里,我发现和之间的一个区别/../是我们不需要使用\来逃避/。你的实践经验还有什么?

编辑

根据@akashspeaking 的建议,我尝试了这个并找到了他所说的:

> re=%r(2/3)­
=> /2\/3/   # giving the pattern /../. Means Ruby internally converted this %r(..) to /../, which it should not if we created such regexp pattern manually.
> 

从上面很清楚理论上%r(..)是比 /../.

quickbm(10000000) { /2\­/3/=~s }任何人都可以通过执行和quickbm(10000000) { %r(2/3) =~ s }测量执行时间来帮助我。我没有在此处安装所需的 gem 基准测试。但是古玩要知道这两个的输出。如果有的话-您可以在终端上尝试并在此处粘贴详细信息吗?

谢谢

4

4 回答 4

4

%r/foo/和绝对没有区别/foo/

irb(main):001:0> %r[foo]
=> /富/
irb(main):002:0> %r{foo}
=> /富/
irb(main):003:0> /foo/
=> /富/

源脚本将在启动时由解释器分析,两者都将转换为正则表达式,在运行时将是相同的。

唯一的区别是源代码,而不是可执行文件。试试这个:

require 'benchmark'

str = (('a'..'z').to_a * 256).join + 'foo'
n = 1_000_000

puts RUBY_VERSION, n
puts

Benchmark.bm do |b|
  b.report('%r') { n.times { str[%r/foo/] } }
  b.report('/') { n.times { str[/foo/] } }
end

哪个输出:

1.9.3
1000000

      user     system      total        real
%r  8.000000   0.000000   8.000000 (  8.014767)
/  8.000000   0.000000   8.000000 (  8.010062)

这是在运行 10.8.2 的旧 MacBook Pro 上。想一想,这是 6,656,000,000 (26 * 256 * 1,000,000) 个字符被搜索并且都返回了基本相同的值。巧合?我想不是。

在机器上运行此程序并获得在该 CPU 上的两个测试之间显着不同的答案将表明指定同一事物的两种语法不同的方式在运行时性能方面存在差异。我严重怀疑这会发生。


编辑:

多次运行它显示了行动的随机性。我稍微调整了代码,让它在今天早上的基准测试中执行五个循环。系统在运行测试时正在扫描磁盘,因此它们花费了更长的时间,但它们仍然显示出两次运行之间的微小随机差异:

require 'benchmark'

str = (('a'..'z').to_a * 256).join + 'foo'
n = 1_000_000

puts RUBY_VERSION, n
puts

regex = 'foo'
Benchmark.bm(2) do |b|
  5.times do
    b.report('%r') { n.times { str[%r/#{ regex }/] } }
    b.report('/')  { n.times { str[/#{ regex }/] } }
  end
end

结果:

      # user     system      total        real
%r  12.440000   0.030000  12.470000 ( 12.475312)
/   12.420000   0.030000  12.450000 ( 12.455737)
%r  12.400000   0.020000  12.420000 ( 12.431750)
/   12.400000   0.020000  12.420000 ( 12.417107)
%r  12.430000   0.030000  12.460000 ( 12.467275)
/   12.390000   0.020000  12.410000 ( 12.418452)
%r  12.400000   0.030000  12.430000 ( 12.432781)
/   12.390000   0.020000  12.410000 ( 12.412609)
%r  12.410000   0.020000  12.430000 ( 12.427783)
/   12.420000   0.020000  12.440000 ( 12.449336)

大约两秒钟后运行:

      # user     system      total        real
%r  12.360000   0.020000  12.380000 ( 12.390146)
/   12.370000   0.030000  12.400000 ( 12.391151)
%r  12.370000   0.020000  12.390000 ( 12.397819)
/   12.380000   0.020000  12.400000 ( 12.399413)
%r  12.410000   0.020000  12.430000 ( 12.440236)
/   12.420000   0.030000  12.450000 ( 12.438158)
%r  12.560000   0.040000  12.600000 ( 12.969364)
/   12.640000   0.050000  12.690000 ( 12.810051)
%r  13.160000   0.120000  13.280000 ( 14.624694) # <-- opened new browser window
/   12.650000   0.040000  12.690000 ( 13.040637)

速度没有一致的差异。

于 2013-01-17T04:49:25.687 回答
2

%r(..)在这里,我发现和之间的一个区别/../是我们不需要使用\来逃避/

这是它们的主要用途。与分隔符改变其语义的字符串不同,正则表达式文字之间唯一真正的区别是分隔符本身。

于 2013-01-16T10:24:57.937 回答
1

还请查看此线程Ruby %r{ } 表达式和此文档的 2 段http://www.ruby-doc.org/core-1.9.3/Regexp.html

除了在 %r 而不是 // 之后使用任何符号作为分隔符之外,没有什么区别

于 2013-01-16T10:37:14.490 回答
1

如果使用 %r 表示法,则可以使用任意符号作为分隔符。例如,您可以将正则表达式编写为以下任何一种(以及更多):

%r{pattern}
%r[pattern]
%r(pattern)
%r!pattern!

如果您的正则表达式包含大量“/”,这将很有用

注意:无论您使用什么,它将以默认形式保存。即 %r:pattern: 将默认为 /pattern/

于 2013-01-16T13:00:42.600 回答