获取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]