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.

5voto

tripleee Punkte 155951

Die anderen Antworten hier geben keine vollständige Lösung für Regex-Versionen an, die kein Non-Greedy-Matching unterstützen. Die gierigen Quantoren ( .*? , .+? usw.) sind eine Perl 5-Erweiterung, die in herkömmlichen regulären Ausdrücken nicht unterstützt wird.

Wenn Ihre Abbruchbedingung ein einzelnes Zeichen ist, ist die Lösung einfach: Anstelle von

a(.*?)b

können Sie mit

a[^ab]*b

d.h. eine Zeichenklasse angeben, die die Anfangs- und Endzeichen ausschließt.

Im allgemeineren Fall können Sie akribisch einen Ausdruck konstruieren wie

start(|[^e]|e(|[^n]|n(|[^d])))end

zur Erfassung einer Übereinstimmung zwischen start und das erste Vorkommen von end . Beachten Sie, dass der Unterausdruck mit den verschachtelten Klammern eine Reihe von Alternativen angibt, die zusammen Folgendes ermöglichen e nur, wenn es nicht gefolgt wird von nd und so weiter, und achten Sie auch darauf, die leere Zeichenkette als eine Alternative abzudecken, die nicht mit dem übereinstimmt, was an diesem bestimmten Punkt nicht erlaubt ist.

Natürlich ist es in den meisten Fällen richtig, einen geeigneten Parser für das zu analysierende Format zu verwenden, aber manchmal ist ein solcher vielleicht nicht verfügbar, oder das von Ihnen verwendete Spezialwerkzeug besteht auf einem regulären Ausdruck und sonst nichts.

3voto

Ste Punkte 1213

Hier ist eine andere Möglichkeit.

Hier ist der, den Sie suchen. Das ist faul [\s\S]*?

Der erste Punkt: [\s\S]*?(?:location="[^"]*")[\s\S]* Ersetzen durch: $1

Erläuterung : https://regex101.com/r/ZcqcUm/2


Der Vollständigkeit halber sei gesagt, dass dies das letzte ist. Das ist gierig [\s\S]*

Der letzte Punkt: [\s\S]*(?:location="([^"]*)")[\s\S]* Ersetzen durch: $1

Erläuterung : https://regex101.com/r/LXSPDp/3


Es gibt nur einen Unterschied zwischen diesen beiden regulären Ausdrücken und das ist die ?

2voto

Mohammad Kanan Punkte 4191

Denn Sie verwenden quantifiziertes Teilmuster und wie beschrieben in Perl-Doku ,

Standardmäßig ist ein quantifiziertes Teilmuster " gierig ", das heißt, es wird übereinstimmen als viele Male wie möglich (bei einer bestimmten Ausgangslage) wobei der Rest des Musters immer noch übereinstimmen muss. Wenn Sie es wollen um die Mindestanzahl von Malen zu erreichen möglich, folgen Sie dem Quantifizierer mit a "?" . Beachten Sie, dass sich die Bedeutungen nicht ändern, nur die "Gier":

*?        //Match 0 or more times, not greedily (minimum matches)
+?        //Match 1 or more times, not greedily

So können Sie Ihre quantifiziert Muster, um eine Mindestübereinstimmung zu erzielen, gefolgt von ? :

/location="(.*?)"/

0voto

user13202738 Punkte 49
import regex
text = 'ask her to call Mary back when she comes back'                           
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
    print (match.group(1))

Ausgabe: Maria

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