Сопоставить все вхождения регулярного выражения

467

Есть ли быстрый способ найти каждое соответствие регулярного выражения в Ruby? Я просмотрел объект Regex в Ruby STL и искал в Google безрезультатно.

  • 2
    Я прочитал это, как я могу искать строку для всех шаблонов регулярных выражений и был ужасно смущен ...
Теги:

3 ответа

660
Лучший ответ

Использование scan должно сделать трюк:

string.scan(/regex/)
  • 9
    Но что упираться в этот случай? "соответствуй мне!". scan (/.../) = ["mat", "ch" "me!" ], но все вхождения /.../ были бы ["mat", "atc", "tch", "ch", ...]
  • 12
    Не было бы. /.../ - нормальное жадное регулярное выражение. Он не будет возвращаться к подобранному контенту. Вы можете попробовать использовать ленивое регулярное выражение, но даже этого, вероятно, будет недостаточно. взгляните на regexp doc ruby-doc.org/core-1.9.3/Regexp.html, чтобы правильно выразить свое регулярное выражение :)
Показать ещё 13 комментариев
30

Чтобы найти все соответствующие строки, используйте scan метод String.

str = "A 54mpl3 string w1th 7 numb3rs scatter36 ar0und"
str.scan(/\d+/)
#=> ["54", "3", "1", "7", "3", "36", "0"]

Если вы предпочитаете MatchData, который является типом возвращаемого объекта, match метод Regexp, используйте следующие

str.to_enum(:scan, /\d+/).map { Regexp.last_match }
#=> [#<MatchData "54">, #<MatchData "3">, #<MatchData "1">, #<MatchData "7">, #<MatchData "3">, #<MatchData "36">, #<MatchData "0">]

Преимущество использования MatchData заключается в том, что вы можете использовать такие методы, как offset

match_datas = str.to_enum(:scan, /\d+/).map { Regexp.last_match }
match_datas[0].offset(0)
#=> [2, 4]
match_datas[1].offset(0)
#=> [7, 8]

Обратите внимание на эти вопросы, если вы хотите узнать больше Как получить данные соответствия для всех вхождений регулярного выражения Ruby в строку?
Регулятор соответствия регулярному выражению Ruby с поддержкой именного захвата
Как узнать начальную точку для каждого матча в рубине

Чтение о специальных переменных $&, $', $1, $2 в ruby ​​будет очень полезно.

6

если у вас есть регулярное выражение с группами:

str="A 54mpl3 string w1th 7 numbers scatter3r ar0und"
re=/(\d+)[m-t]/

Для поиска сопоставимых групп используется метод проверки строки:

str.scan re
#> [["54"], ["1"], ["3"]]

Чтобы найти соответствующий шаблон:

str.to_enum(:scan,re).map {$&}
#> ["54m", "1t", "3r"]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню