Geben Sie das erste Match von Ruby Regex zurück

97

Ich suche nach einer Möglichkeit, ein Regex-Match für eine Zeichenfolge in Ruby durchzuführen und es beim ersten Match kurzschließen zu lassen.

Die Zeichenfolge, die ich verarbeite, ist lang und sieht so aus, als würde die Standardmethode ( matchMethode) das Ganze verarbeiten, jede Übereinstimmung sammeln und ein MatchData-Objekt zurückgeben, das alle Übereinstimmungen enthält.

match = string.match(/regex/)[0].to_s
Daniel Beardsley
quelle

Antworten:

134

Du könntest es versuchen variableName[/regular expression/]. Dies ist eine Beispielausgabe von irb:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders"
=> "erik kalle johan anders erik kalle johan anders"
irb(main):004:0> names[/kalle/]
=> "kalle"
Presidenten
quelle
Ist dies nicht ein Match und gibt das erste Ergebnis hinter den Kulissen zurück?
Gishu
7
Nach einigem Benchmarking mit Strings unterschiedlicher Länge und Blick auf die C-Quelle stellt sich heraus, dass Regex.match einen Kurzschluss macht und nur die erste Übereinstimmung findet.
Daniel Beardsley
3
Ordentlich, wusste nichts über diese Abkürzung.
Pierre
Gibt es eine Dokumentation zu dieser Verknüpfung? Ich suchte hoch und niedrig nach einer meiner Meinung nach relativ einfachen Aufgabe und löste mein Problem erst, nachdem ich dies gefunden hatte. Vielen Dank!
dmourati
5
@dmourati Diese Funktion ist in String # [] dokumentiert . Vielen Dank, dass Sie nach dem Dokument gefragt haben, denn beim Lesen habe ich das captureArgument gefunden, mit dem Sie anstelle der vollständigen Übereinstimmung ein Capture zurückgeben können.
Faultier
68

Sie können verwenden []: (was ist wie match)

"[email protected]"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"[email protected]"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"
Benjamin Crouzier
quelle
4
beste vollständige Antwort
akostadinov
23

Wenn nur das Vorhandensein einer Übereinstimmung wichtig ist, können Sie mitgehen

/regexp/ =~ "string"

In beiden Fällen matchsollte nur der erste Treffer zurückgegeben werden, während scandie gesamte Zeichenfolge durchsucht wird. Deshalb wenn

matchData = "string string".match(/string/)
matchData[0]    # => "string"
matchData[1]    # => nil - it's the first capture group not a second match
Slartibartfast
quelle
8

Ich bin mir noch nicht sicher, ob diese Funktion fantastisch oder einfach nur verrückt ist, aber Ihre Regex kann lokale Variablen definieren.

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0
dollars #=> "3"

(Entnommen aus http://ruby-doc.org/core-2.1.1/Regexp.html ).

Felix
quelle
Super Feature! Genau das, was ich brauchte
RaphaMex
Vorsichtsmaßnahme: Es funktioniert nur, wenn regex =~ string", not when string = ~ regex`
Christopher Oezbek
2

Ein regulärer Ausdruck (regulärer Ausdruck) ist nichts anderes als eine endliche Zustandsmaschine (FSM).

Ein FSM versucht die Frage zu beantworten "Ist dieser Zustand möglich oder nicht?"

Es wird so lange versucht, eine Musterübereinstimmung vorzunehmen, bis eine Übereinstimmung gefunden wird (Erfolg) oder bis alle Pfade erkundet wurden und keine Übereinstimmung gefunden wurde (Fehler).

Bei Erfolg die Frage "Ist dieser Zustand möglich oder nicht?" wurde mit "Ja" beantwortet. Daher ist kein weiterer Abgleich erforderlich und der Regex kehrt zurück.

Sehen Sie diese und diese für weitere Informationen hierzu.

Weiter: Hier ist ein interessantes Beispiel , um zu demonstrieren, wie Regex funktioniert. Hier wird ein regulärer Ausdruck verwendet, um zu erkennen, ob eine gegebene Zahl eine Primzahl ist. Dieses Beispiel ist in Perl, kann aber auch in Ruby geschrieben werden.

Lackmus
quelle