【问题标题】:What is the difference between =~ and match() when pattern matching?模式匹配时 =~ 和 match() 有什么区别?
【发布时间】:2013-01-15 18:07:19
【问题描述】:

我正在使用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

【问题讨论】:

  • 为什么不给我一票?
  • operatormethod 可能在做同样的事情,但它们的功能差异太大 - 两个帖子都包含太多信息,这真的很棒而且很有帮助的知识信息适用于所有 SO 用户。尽管有所有这些,但我的投票对我来说真的很糟糕!我没想到论坛上会出现这种情况。
  • 我没有对你投反对票,但我想这是因为所写的问题有点荒谬。您发现有不止一种方法可以执行类似的操作,但每种方法都返回不同的结果。为什么这很有趣? Ruby(以及大多数编程语言)中有许多方法可以做类似的事情但返回不同的结果。
  • @Phrogz 如果 OP 期望他们做同样的事情会很有趣(例如,String#==String#eql?)。通过更多的研究当然可以找到答案,但这是一个公平的初学者问题。
  • 问题不是它是否有趣(这是主观的),而是方法之间的差异。

标签: ruby regex ruby-1.9.3


【解决方案1】:

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

运算符=~返回第一个匹配的索引(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(以及MatchDataString 上的部分)。

【讨论】:

  • +1 给你!你的发现是完美的,明白了!但我仍然对hash 你想说的话感到困惑!你能用代码或其他东西解释一下吗?这样我就可以看到你的想法!请
  • @DoLoveSky 使用 irb 编辑了一些输出。
  • @DoLoveSky 我强烈建议您通读我的回答中引用的 ruby​​ 文档。那里有更多可能非常有用的信息。
  • 是的,先生 :) 我现在正在这样做。我只是喜欢我帖子中的两个答案!
【解决方案2】:

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

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

=~ 通常用在条件句中,当你只关心 if 匹配时:

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'

【讨论】:

  • +1 给你!很好的解释。你提供给我的信息很多。非常感谢!
  • +1 仅用于第一段。 (其余的也很好。:)
  • 重要的不仅仅是返回值。还有一点:速度。原则上,match=~ 进行更广泛的计算是可能的(尽管实际上并非如此),因此这可能是决定使用哪个的因素之一。这不是一个奇怪的问题。我认为你的红色与蓝色的论点没有任何意义。
  • @AlexWayne 我想再次感谢您在帖子中提出最有价值的观点!
  • 任何有兴趣的人我用=~match 做了一个非常简单的基准测试,发现=~ 的速度几乎是match 的两倍:pastie.org/5690542
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-23
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多