12

我正在使用Ruby 1.9.3. 我在玩一些模式,发现了一些有趣的东西:

示例 1:

irb(main):001:0> /hay/ =~  'haystack'
=> 0
irb(main):003:0> /st/ =~ 'haystack'
=> 3

示例 2:

irb(main):002:0> /hay/.match('haystack')
=> #<MatchData "hay">
irb(main):004:0> /st/.match('haystack')
=> #<MatchData "st">

=~返回其第一个匹配的第一个位置,而match返回模式。除此之外,=~和之间有什么区别match()吗?

执行时间差 (根据@Casper)

irb(main):005:0> quickbm(10000000) { "foobar" =~ /foo/ }
Rehearsal ------------------------------------
   8.530000   0.000000   8.530000 (  8.528367)
--------------------------- total: 8.530000sec

       user     system      total        real
   8.450000   0.000000   8.450000 (  8.451939)
=> nil

irb(main):006:0> quickbm(10000000) { "foobar".match(/foo/) }
Rehearsal ------------------------------------
  15.360000   0.000000  15.360000 ( 15.363360)
-------------------------- total: 15.360000sec

       user     system      total        real
  15.240000   0.010000  15.250000 ( 15.250471)
=> nil
4

2 回答 2

10

首先确保您使用了正确的运算符:=~是正确的,~=不是。

运算符=~返回第一个匹配项的索引(nil如果不匹配)并将 存储MatchData在全局变量$~中。命名的捕获组分配给 上的散列$~,并且当RegExp是运算符左侧的文字时,也分配给具有这些名称的局部变量。

>> str = "Here is a string"
>> re = /(?<vowel>[aeiou])/    # Contains capture group named "vowel"
>> str =~ re
=> 1
>> $~
=> #<MatchData "e" vowel:"e">
>> $~[:vowel]    # Accessible using symbol...
=> "e"
>> $~["vowel"]    # ...or string
=> "e"
>> /(?<s_word>\ss\w*)/ =~ str
=> 9
>> s_word # This was assigned to a local variable
=> " string"

该方法match返回MatchData自身(再次,nil如果不匹配)。在这种情况下,方法调用两侧的命名捕获组被分配给返回的MatchData.

>> m = str.match re
=> #<MatchData "e" vowel:"e">
>> m[:vowel]
=> "e"

有关详细信息,请参阅http://www.ruby-doc.org/core-1.9.3/Regexp.html(以及关于MatchData和的部分String)。

于 2013-01-15T18:21:44.290 回答
4

当您有一个不修改状态的方法时,重要的是返回值。那么除了颜色之外,红色和蓝色还有什么区别?我的观点是,这是一个奇怪的问题,你似乎已经知道答案了。(@sawa 让我直奔这里)

nil但话虽如此,当正则表达式不匹配时,这两种方法都会返回(一个虚假值)。而且,这两种方法在匹配时都会返回一个真值。=~返回一个整数,表示匹配的第一个字符,即使是0, 因为0在 Ruby 中是真值。 match返回一个包含非常详细的匹配数据的对象,当您需要大量关于匹配的信息时,这很方便。

=~通常在条件句中使用,当您只关心是否匹配时:

do_stuff if "foobar" =~ /foo/
do_stuff if "foobar".match(/foo/) # same effect, but probably slower and harder to read

match当您需要有关匹配内容的详细信息时,通常使用:

 name = "name:bob".match(/^name:(\w+)$/)[1]
 puts name #=> 'bob'
于 2013-01-15T18:22:13.313 回答