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
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.)
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
Versuche dies
(.*?quick.*?)z