wake-up-neo.com

Regex bis aber nicht inklusive

Für reguläre Ausdrücke: Wie lautet die Syntax für die Suche bis, jedoch ohne Berücksichtigung? In etwa wie:

Haystack:
The quick red fox jumped over the lazy brown dog

Expression:
.*?quick -> and then everything until it hits the letter "z" but do not include z
61
NoodleOfDeath

Der explizite Ausdruck "Suche bis X, jedoch ohne X" lautet:

(?:(?!X).)*

dabei kann X ein beliebiger regulärer Ausdruck sein.

In Ihrem Fall könnte dies jedoch übertrieben sein - hier wäre der einfachste Weg

[^z]*

Dies passt zu allem außer z und stoppt daher direkt vor dem nächsten z.

Also wird .*?quick[^z]* Mit The quick fox jumps over the la Übereinstimmen.

Sobald Sie jedoch mehr als einen einfachen Buchstaben haben, auf den Sie achten müssen, kommt beispielsweise (?:(?!X).)* Ins Spiel

(?:(?!lazy).)* - Finde eine Übereinstimmung bis zum Beginn des Wortes lazy.

Dies verwendet eine Lookahead-Behauptung, genauer gesagt einen negativen Lookahead.

.*?quick(?:(?!lazy).)* stimmt mit The quick fox jumps over the überein.

Erklärung:

(?:        # Match the following but do not capture it:
 (?!lazy)  # (first assert that it's not possible to match "lazy" here
 .         # then match any character
)*         # end of group, zero or more repetitions.

Wenn Sie nach Schlüsselwörtern suchen, möchten Sie diese möglicherweise mit Word-Begrenzungsankern umgeben: \bfox\b Stimmt nur mit dem vollständigen Wort fox überein, nicht mit dem Fuchs in foxy.

Hinweis

Wenn der zuzuordnende Text auch Zeilenumbrüche enthalten kann, müssen Sie die Option "Punkt entspricht allen" Ihrer Regex-Engine festlegen. Normalerweise können Sie dies erreichen, indem Sie dem regulären Ausdruck (?s) Voranstellen. Dies funktioniert jedoch nicht in allen regulären Ausdrücken (insbesondere JavaScript).

Alternative Lösung:

In vielen Fällen können Sie auch eine einfachere, besser lesbare Lösung verwenden, die einen Lazy Quantifier verwendet. Durch Hinzufügen eines ? Zum * - Quantifizierer wird versucht, so wenig Zeichen wie möglich von der aktuellen Position abzugleichen:

.*?(?=(?:X)|$)

passt auf eine beliebige Anzahl von Zeichen und stoppt direkt vor X (das kann ein beliebiger regulärer Ausdruck sein) oder dem Ende der Zeichenfolge (wenn X nicht passt). Möglicherweise müssen Sie auch die Option "Punkt entspricht allen" festlegen, damit dies funktioniert. (Hinweis: Ich habe eine nicht erfassende Gruppe um X hinzugefügt, um sie zuverlässig vom Wechsel zu isolieren.)

142
Tim Pietzcker

Ein Lookahead-Regex-Syntax kann Ihnen helfen, Ihr Ziel zu erreichen. Also ein regulärer Ausdruck für dein Beispiel ist

.*?quick.*?(?=z)

Und es ist wichtig, das .*? Lazy Matching vor dem (?=z) lookahead: Der Ausdruck stimmt mit einem Teilstring überein, bis zum ersten Auftreten des Buchstabens z.

Hier ist ein C # -Codebeispiel:

const string text = "The quick red fox jumped over the lazy brown dogz";

string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value;
Console.WriteLine(lazy); // The quick red fox jumped over the la

string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value;
Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog
10
Igor Kustov

Versuche dies

(.*?quick.*?)z
0
Max