Reputation: 14189
I need a function to return all matches of a regexp in a string and positions at which the matches are found (I want to highlight matches in the string).
There is String#match that returns MatchData, but only for the first match.
Is there a better way to do this than something like
matches = []
begin
match = str.match(regexp)
break unless match
matches << match
str = str[match.end(0)..-1]
retry
end
Upvotes: 7
Views: 2066
Reputation: 2656
Use the captures method on a successful match.
"foobar".match(/(f)(oobar)/).captures
=> ["f,""oobar"]
Upvotes: 1
Reputation: 24010
I think at least you can enhance your code a bit:
matches = []
while(match = str.match(regexp))
matches << match
str = match.post_match
end
Upvotes: 0
Reputation: 31438
Do you really need the position or is it enough to replace the matches on the fly?
s="I'mma let you finish but Beyonce had one of the best music videos of all time!"
s.gsub(/(Beyonce|best)/, '<b>\1</b>')
=> "I'mma let you finish but Beyonce had one of the best music videos of all time!"
Upvotes: 2
Reputation: 370357
If you just need to iterate over the MatchData objects you can use Regexp.last_match in the scan-block, like:
string.scan(regex) do
match_data = Regexp.last_match
do_something_with(match_data)
end
If you really need an array, you can use:
require 'enumerator' # Only needed for ruby 1.8.6
string.enum_for(:scan, regex).map { Regexp.last_match }
Upvotes: 11