59

In other languages, in RegExp you can use /.../g for a global match.

However, in Ruby:

"hello hello".match /(hello)/

Only captures one hello.

How do I capture all hellos?

Boken
  • 4,825
  • 10
  • 32
  • 42
never_had_a_name
  • 90,630
  • 105
  • 267
  • 383

3 Answers3

76

You can use the scan method. The scan method will either give you an array of all the matches or, if you pass it a block, pass each match to the block.

"hello1 hello2".scan(/(hello\d+)/)   # => [["hello1"], ["hello2"]]

"hello1 hello2".scan(/(hello\d+)/).each do|m|
  puts m
end

I've written about this method, you can read about it here near the end of the article.

AboutRuby
  • 7,936
  • 2
  • 27
  • 20
  • 8
    No need to do `each`. Just `.scan(...){|m|...}` – Nakilon Sep 28 '10 at 23:15
  • 4
    Great; one additional pointer: if your regex need only be captured as a whole (no subgroups), omitting the enclosing `()` will give you a regular, flat array. If you specify at least 1 subgroup, you'll get a nested array (whose subarrays do NOT include the whole match - only the subgroup captures). – mklement0 Jun 12 '13 at 15:31
15

Here's a tip for anyone looking for a way to replace all regex matches with something else.

Rather than the //g flag and one substitution method like many other languages, Ruby uses two different methods instead.

# .sub — Replace the first
"ABABA".sub(/B/, '') # AABA

# .gsub — Replace all
"ABABA".gsub(/B/, '') # AAA
ivanreese
  • 2,718
  • 3
  • 30
  • 36
12

use String#scan. It will return an array of each match, or you can pass a block and it will be called with each match.

All the details at http://ruby-doc.org/core/classes/String.html#M000812

wuputah
  • 11,285
  • 1
  • 43
  • 60