Ruby字符串上的扫描和匹配有什么区别

时间:2011-11-03 10:53:52

标签: ruby regex

我是Ruby的新手,并且一直使用String.scan来搜索第一次出现的数字。返回值是嵌套数组有点奇怪,但我只需要[0][0]获取我想要的值。 (我确信它有其目的,只是我还没有使用它。)

我刚发现有String.match方法。它看起来更方便,因为返回的数组没有嵌套。

这是两个例子,首先是扫描:

>> 'a 1-night stay'.scan(/(a )?(\d*)[- ]night/i).to_a
=> [["a ", "1"]]

然后是匹配

>> 'a 1-night stay'.match(/(a )?(\d*)[- ]night/i).to_a
=> ["a 1-night", "a ", "1"]

我已经检查了API,但我无法区分差异,因为两者都提到了“匹配模式”。

这个问题仅仅是出于好奇,scan可以做match无法做到的事情,反之亦然。任何只有一个人可以完成的特定场景? matchscan的劣势吗?

3 个答案:

答案 0 :(得分:48)

简短回答:scan将返回所有匹配项。这并不会使它更优越,因为如果您只想要第一场比赛,str.match[2]读取的内容要比str.scan[0][1]好得多。

ruby-1.9.2-p290 :002 > 'a 1-night stay, a 2-night stay'.scan(/(a )?(\d*)[- ]night/i).to_a
 => [["a ", "1"], ["a ", "2"]] 
ruby-1.9.2-p290 :004 > 'a 1-night stay, a 2-night stay'.match(/(a )?(\d*)[- ]night/i).to_a
 => ["a 1-night", "a ", "1"] 

答案 1 :(得分:20)

#scan返回正则表达式匹配的所有内容。

#match将第一个匹配作为MatchData对象返回,该对象包含由$&等特殊变量保存的数据(正则表达式匹配的内容;这是映射到索引0的内容), $1(匹配1),$2,等等。

答案 2 :(得分:1)

先前的回答指出,扫描将从调用该方法的字符串中返回所有匹配项,但这是不正确的。

扫描会跟踪索引,并在上一个匹配的最后一个字符之后继续查找后续的匹配。

string = 'xoxoxo'

p string.scan('xo') # => ['xo' 'xo' 'xo' ]
# so far so good but...

p string.scan('xox') # => ['xox']
# if this retured EVERY instance of 'xox' it would include a substring
# starting at indices 0 and 2 but only one match is found