829 Stimmen

Regulärer Ausdruck, der bei der ersten Übereinstimmung endet

Mein Regex-Muster sieht etwa so aus

<xxxx location="file path/level1/level2" xxxx some="xxx">

Ich interessiere mich nur für den Teil in Anführungszeichen, der dem Standort zugeordnet ist. Sollte es nicht so einfach sein wie unten ohne den gierigen Schalter?

/.*location="(.*)".*/

Es scheint nicht zu funktionieren.

0 Stimmen

Was ist Ihre Quelle, ist es HTML oder xml oder etwas anderes?

2 Stimmen

Nun, die Quelle ist eine XML-Datei, aber ich fülle bestimmte Tags in eine Textdatei ein. Für meine Zwecke wird diese Regex wahrscheinlich ausreichen.

1613voto

Daniel Vandersluis Punkte 87406

Sie müssen Ihren regulären Ausdruck faul/nicht gierig machen, weil er standardmäßig, "(.*)" wird mit allen von "file path/level1/level2" xxx some="xxx" .

Stattdessen können Sie Ihren Punkt-Stern so gestalten, dass er nicht gierig ist und mit möglichst wenigen Zeichen übereinstimmt:

/location="(.*?)"/

Hinzufügen einer ? auf einen Quantifizierer ( ? , * o + ) macht es nicht gierig.

Hinweis: Dies ist nur in Regex-Engines verfügbar, die die Perl 5-Erweiterungen implementieren (Java, Ruby, Python, etc.), nicht aber in "traditionellen" Regex-Engines (einschließlich Awk, sed , grep sin -P , usw.).

50 Stimmen

FWIW, für den Fall, dass Sie VIM verwenden, muss diese Regex ein wenig anders sein: anstelle von .*? Es ist .\{-} für ein nicht gieriges Spiel.

1 Stimmen

Javascript hace Unterstützung faule Quantoren .

0 Stimmen

Wie man die nicht gierige Fanggruppe nachahmt für awk s ohne gensub() : mawk 'sub("\42",___, $(_+=++_))+sub("^",__, $_)+gsub("^.*" __"|" ___".*$","")^(_-=_)' ___='\31\21' __='\37\27' FS=' location=\42' ::::::::::::::: >>>>> file path/level1/level2

93voto

sepp2k Punkte 352762

location="(.*)" wird von der " nach location= bis die " nach some="xxx es sei denn, man macht es nicht gierig.

Sie brauchen also entweder .*? (d.h. machen Sie es nicht gierig, indem Sie ? ) oder besser ersetzen .* con [^"]* .

  • [^"] Passt auf jedes Zeichen außer einem " <Anführungszeichen>
  • Mehr generisch: [^abc] - Passt auf jedes Zeichen außer einem a, b oder c

8 Stimmen

[^"]* ist bei den meisten Regex-Engines wahrscheinlich auch schneller, weil sie das Muster nach dem aktuellen Muster nicht nachschlagen müssen.

2 Stimmen

@Kip: Du hast wahrscheinlich recht, aber die .*? Notation ist allgemeiner als [^"]*

0 Stimmen

Wie wäre es, wenn ich das Begrenzungszeichen mit [^"]* einfügen möchte

48voto

user193690 Punkte 1

Wie wäre es mit

.*location="([^"]*)".*

Dadurch wird die unbegrenzte Suche mit .* vermieden, und es wird genau bis zum ersten Anführungszeichen gesucht.

2 Stimmen

Aufgrund von Unstimmigkeiten in grep das obige Muster sollte bevorzugt werden, wenn die Übertragbarkeit ein Anliegen ist.

39voto

codenheim Punkte 19712

Verwenden Sie Non-Greedy-Matching, wenn Ihr Motor dies unterstützt. Fügen Sie das ? innerhalb der Erfassung hinzu.

/location="(.*?)"/

23voto

Uddhav P. Gautam Punkte 6634

Verwendung von Lazy-Quantoren ? ohne globale Flagge ist die Antwort.

Beispiel,

enter image description here

Wenn Sie die globale Flagge /g dann hätte es alle Übereinstimmungen mit der geringsten Länge wie unten angegeben gefunden. enter image description here

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X