Есть ли такая функция, как String # scan, но возвращающая массив MatchDatas? - PullRequest
6 голосов
/ 18 сентября 2009

Мне нужна функция для возврата всех совпадений регулярного выражения в строке и позиций, в которых найдены совпадения (я хочу выделить совпадения в строке).

Существует строка соответствия, которая возвращает MatchData, но только для первого совпадения.

Есть ли лучший способ сделать это, чем что-то вроде

matches = []
begin
  match = str.match(regexp)
  break unless match
  matches << match
  str = str[match.end(0)..-1]
  retry
end

Ответы [ 4 ]

11 голосов
/ 18 сентября 2009

Если вам просто нужно перебрать объекты MatchData, вы можете использовать Regexp.last_match в блоке сканирования, например:

string.scan(regex) do
  match_data = Regexp.last_match
  do_something_with(match_data)
end

Если вам действительно нужен массив, вы можете использовать:

require 'enumerator' # Only needed for ruby 1.8.6
string.enum_for(:scan, regex).map { Regexp.last_match }
2 голосов
/ 18 сентября 2009

Вам действительно нужна позиция или этого достаточно, чтобы заменить спички на лету?

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>')

=> "Я хочу, чтобы ты закончил, но Beyonce имел один из лучших музыкальных клипов всех времен!"

1 голос
/ 08 октября 2014

Используйте метод captures при успешном совпадении.

"foobar".match(/(f)(oobar)/).captures

=> ["f," "oobar"]

0 голосов
/ 18 сентября 2009

Я думаю, по крайней мере, вы можете немного улучшить свой код:

matches = []
while(match = str.match(regexp)) 
  matches << match
  str = match.post_match
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...