tags:

views:

80

answers:

2

I want to get the index as well as the results of a scan

"abab".scan(/a/)

I would like to have not only

=> ["a", "a"]

but also the index of those matches

[1, 3]

any suggestion?

+4  A: 

Try this:

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

res.inspect # => [["a", 0], ["a", 2]]
Todd Yandell
thanks, that works!
adn
@Todd's answer is right. However if you prefer to avoid using the slightly cryptic special variables like `$~` then `Regexp.last_match` is equivalent. i.e. you can say `Regexp.last_match.offset(0)[0]`
mikej
or even `Regexp.last_match.offset(0).first`
gnibbler
+1  A: 

It surprised me that there isn't any method similar to String#scan which would return array of MatchData objects, similar to String#match. So, if you like monkey-patching, you can combine this with Todd's solution (Enumerator is introduced in 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]
Mladen Jablanović