Но что упираться в этот случай? "соответствуй мне!". scan (/.../) = ["mat", "ch" "me!" ], но все вхождения /.../ были бы ["mat", "atc", "tch", "ch", ...]
Майкл Диккенс
13
Не было бы. /.../ - нормальное жадное регулярное выражение. Он не будет возвращаться к подобранному контенту. Вы можете попробовать использовать ленивое регулярное выражение, но даже этого, вероятно, будет недостаточно. взгляните на regexp doc ruby-doc.org/core-1.9.3/Regexp.html, чтобы правильно выразить свое регулярное выражение :)
Жан
49
это похоже на Ruby WTF ... почему это на String вместо Regexp с другими вещами regexp? Это даже нигде не упоминается в документах для Regexp
Anentropic
9
Я думаю, это потому, что он определен и вызван для String, а не для Regex ... Но это действительно имеет смысл. Вы можете написать регулярное выражение для захвата всех совпадений, используя Regex # match, и перебирать захваченные группы. Здесь вы пишете функцию частичного соответствия и хотите, чтобы она применялась несколько раз к заданной строке, это не является обязанностью Regexp. Я предлагаю вам проверить реализацию сканирования для лучшего понимания: ruby-doc.org/core-1.9.3/String.html#method-i-scan
Jean
9
@MichaelDickens: В этом случае вы можете использовать /(?=(...))/.
Конрад Боровски,
67
Чтобы найти все подходящие строки, используйте scanметод String .
Может быть, вы неправильно поняли. Регулярное выражение примера пользователя, на который я ответил, было: /(\d+)[m-t]/не /\d+[m-t]/писать: то re = /(\d+)[m-t]/; str.scan(re)же самое, str.scan(/(\d+)[mt]/)но я получаю #>, [["" 54 "], [" 1 "], [" 3 "]]а не "54m", "1t", "3r"]вопрос: было ли у меня регулярное выражение с группой, и я хочу захватить все шаблоны, не меняя регулярные выражение (выход из группы), как я могу это сделать? В этом смысле возможное решение, хотя и немного загадочное и трудное для чтения, было:str.to_enum(:scan,re).map {$&}
MVP
-1
Вы можете использовать string.scan(your_regex).flatten. Если ваше регулярное выражение содержит группы, оно вернется в виде одного простого массива.
Удалите группу из, your_regex = /(\d+)[m-t]/и вам не нужно будет использовать flatten. Ваш последний пример использует, last_matchкоторый в этом случае, вероятно, является безопасным, но является глобальным и может быть перезаписан, если перед вызовом было найдено какое-либо регулярное выражение last_match. Вместо этого, вероятно, безопаснее использовать string.match(regex).captures # => ["group_photo", "jpg"]или, string.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]как показано в других ответах, в зависимости от схемы и потребностей.
Ответы:
Использование
scan
должно сделать трюк:источник
/(?=(...))/
.Чтобы найти все подходящие строки, используйте
scan
метод String .Если хотите, то
MatchData
есть тип объекта, возвращаемого методом Regexpmatch
, используйте:Преимущество использования
MatchData
заключается в том, что вы можете использовать такие методы, какoffset
:Посмотрите эти вопросы, если вы хотите узнать больше:
Чтение о специальных переменных
$&
,$'
,$1
,$2
в Ruby , будет полезно тоже.источник
если у вас есть регулярное выражение с группами:
Вы можете использовать
scan
метод String для поиска подходящих групп:Чтобы найти соответствующий шаблон:
источник
str.scan(/\d+[m-t]/) # => ["54m", "1t", "3r"]
более идиоматичен, чемstr.to_enum(:scan,re).map {$&}
/(\d+)[m-t]/
не/\d+[m-t]/
писать: тоre = /(\d+)[m-t]/; str.scan(re)
же самое,str.scan(/(\d+)[mt]/)
но я получаю #>,[["" 54 "], [" 1 "], [" 3 "]]
а не"54m", "1t", "3r"]
вопрос: было ли у меня регулярное выражение с группой, и я хочу захватить все шаблоны, не меняя регулярные выражение (выход из группы), как я могу это сделать? В этом смысле возможное решение, хотя и немного загадочное и трудное для чтения, было:str.to_enum(:scan,re).map {$&}
Вы можете использовать
string.scan(your_regex).flatten
. Если ваше регулярное выражение содержит группы, оно вернется в виде одного простого массива.Regex также может быть именованной группой.
Вы также можете использовать
gsub
, это просто еще один способ, если вы хотите MatchData.источник
your_regex = /(\d+)[m-t]/
и вам не нужно будет использоватьflatten
. Ваш последний пример использует,last_match
который в этом случае, вероятно, является безопасным, но является глобальным и может быть перезаписан, если перед вызовом было найдено какое-либо регулярное выражениеlast_match
. Вместо этого, вероятно, безопаснее использоватьstring.match(regex).captures # => ["group_photo", "jpg"]
или,string.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]
как показано в других ответах, в зависимости от схемы и потребностей.