Gibt es eine schnelle Möglichkeit, jede Übereinstimmung eines regulären Ausdrucks in Ruby zu finden? Ich habe das Regex-Objekt in der Ruby STL durchsucht und vergeblich bei Google gesucht.
Gibt es eine schnelle Möglichkeit, jede Übereinstimmung eines regulären Ausdrucks in Ruby zu finden? Ich habe das Regex-Objekt in der Ruby STL durchsucht und vergeblich bei Google gesucht.
Antworten:
Verwenden scan
sollte den Trick tun:
string.scan(/regex/)
/(?=(...))/
.
Verwenden Sie die String- scan
Methode, um alle übereinstimmenden Zeichenfolgen zu finden .
str = "A 54mpl3 string w1th 7 numb3rs scatter36 ar0und"
str.scan(/\d+/)
#=> ["54", "3", "1", "7", "3", "36", "0"]
Wenn Sie möchten, MatchData
welchen Typ das von der Regexp- match
Methode zurückgegebene Objekt hat , verwenden Sie:
str.to_enum(:scan, /\d+/).map { Regexp.last_match }
#=> [#<MatchData "54">, #<MatchData "3">, #<MatchData "1">, #<MatchData "7">, #<MatchData "3">, #<MatchData "36">, #<MatchData "0">]
Der Vorteil der Verwendung MatchData
besteht darin, dass Sie Methoden wie die offset
folgenden verwenden können :
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]
Sehen Sie sich diese Fragen an, wenn Sie mehr wissen möchten:
Lesen Sie weiter über spezielle Variablen $&
, $'
, $1
, $2
in Ruby wird auch hilfreich sein.
Wenn Sie einen regulären Ausdruck mit Gruppen haben:
str="A 54mpl3 string w1th 7 numbers scatter3r ar0und"
re=/(\d+)[m-t]/
Sie können die String- scan
Methode verwenden, um übereinstimmende Gruppen zu finden:
str.scan re
#> [["54"], ["1"], ["3"]]
So finden Sie das passende Muster:
str.to_enum(:scan,re).map {$&}
#> ["54m", "1t", "3r"]
str.scan(/\d+[m-t]/) # => ["54m", "1t", "3r"]
ist idiomatischer alsstr.to_enum(:scan,re).map {$&}
/(\d+)[m-t]/
Nicht /\d+[m-t]/
schreiben: re = /(\d+)[m-t]/; str.scan(re)
ist derselbe, str.scan(/(\d+)[mt]/)
aber ich erhalte #> [["" 54 "], [" 1 "], [" 3 "]]
und nicht "54m", "1t", "3r"]
Die Frage war: Wenn ich einen regulären Ausdruck mit einer Gruppe habe und alle Muster erfassen möchte, ohne den regulären zu ändern Ausdruck (Verlassen der Gruppe), wie kann ich das machen? In diesem Sinne war eine mögliche Lösung, wenn auch etwas kryptisch und schwer zu lesen ,:str.to_enum(:scan,re).map {$&}
Sie können verwenden string.scan(your_regex).flatten
. Wenn Ihre Regex Gruppen enthält, wird sie in einem einzelnen einfachen Array zurückgegeben.
string = "A 54mpl3 string w1th 7 numbers scatter3r ar0und"
your_regex = /(\d+)[m-t]/
string.scan(your_regex).flatten
=> ["54", "1", "3"]
Regex kann auch eine benannte Gruppe sein.
string = 'group_photo.jpg'
regex = /\A(?<name>.*)\.(?<ext>.*)\z/
string.scan(regex).flatten
Sie können auch verwenden gsub
, es ist nur eine weitere Möglichkeit, wenn Sie MatchData möchten.
str.gsub(/\d/).map{ Regexp.last_match }
your_regex = /(\d+)[m-t]/
und Sie müssen sie nicht verwenden flatten
. Ihr letztes Beispiel verwendet, last_match
was in diesem Fall wahrscheinlich sicher ist, aber global ist und möglicherweise überschrieben werden könnte, wenn vor dem Aufruf ein regulärer Ausdruck gefunden wurdelast_match
. Stattdessen ist es wahrscheinlich sicherer zu verwenden string.match(regex).captures # => ["group_photo", "jpg"]
oder string.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]
wie in anderen Antworten gezeigt, je nach Muster und Anforderungen.