我是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
无法做到的事情,反之亦然。任何只有一个人可以完成的特定场景? match
是scan
的劣势吗?
答案 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