获取ruby中的字符串扫描结果索引

我想得到索引以及扫描结果

"abab".scan(/a/) 

我不仅想拥有

 => ["a", "a"] 

还有那些比赛的索引

 [1, 3] 

有什么建议吗?

试试这个:

 res = [] "abab".scan(/a/) do |c| res << [c, $~.offset(0)[0]] end res.inspect # => [["a", 0], ["a", 2]] 

根据您的预期行为,这里有一个值得关注的问题。

如果你在"dadad"搜索/dad/你只能获得[["dad",0]]因为scan会在找到一个匹配时前进到每个匹配的末尾(这对我来说是错误的)。

我提出了这个选择:

 def scan_str(str, pattern) res = [] (0..str.length).each do |i| res << [Regexp.last_match.to_s, i] if str[i..-1] =~ /^#{pattern}/ end res end 

如果你想要,你也可以使用标准库中的StringScanner做类似的事情,对于长字符串来说可能会更快。

与@jim所说的非常类似,对于更长的字符串效果更好:

 def matches str, pattern arr = [] while (str && (m = str.match pattern)) offset = m.offset(0).first arr << offset + (arr[-1] ? arr[-1] + 1 : 0) str = str[(offset + 1)..-1] end arr end 

令我感到惊讶的是,没有任何类似于String#scan方法会返回MatchData对象的数组,类似于String#match 。 所以,如果你喜欢猴子修补,你可以将它与Todd的解决方案结合起来( Enumerator在1.9中引入):

 class Regexp def scan str Enumerator.new do |y| str.scan(self) do y << Regexp.last_match end end end end #=> nil /a/.scan('abab').map{|m| m.offset(0)[0]} #=> [0, 2]