Was ist für Regex die Syntax für die Suche bis, aber nicht eingeschlossen? 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
Was ist für Regex die Syntax für die Suche bis, aber nicht eingeschlossen? 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
Antworten:
Die explizite Art zu sagen "suchen bis X
aber nicht einschließen X
" ist:
(?:(?!X).)*
wo X
kann ein 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 hört daher kurz vor dem nächsten auf z
.
Also .*?quick[^z]*
wird passen The quick fox jumps over the la
.
Sobald Sie jedoch mehr als einen einfachen Buchstaben haben, auf den Sie achten müssen, (?:(?!X).)*
kommt er zum Beispiel ins Spiel
(?:(?!lazy).)*
- alles bis zum Wortanfang abgleichen lazy
.
Hierbei wird eine Lookahead-Behauptung verwendet , insbesondere ein negativer Lookahead.
.*?quick(?:(?!lazy).)*
wird übereinstimmen The quick fox jumps over the
.
Erläuterung:
(?: # 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 Wortbegrenzungsankern umgeben: Sie \bfox\b
stimmen nur mit dem vollständigen Wort überein fox
, nicht jedoch mit dem Fuchs in foxy
.
Hinweis
Wenn der abzugleichende Text auch Zeilenumbrüche enthalten kann, müssen Sie die Option "Punkt stimmt mit allen überein" Ihrer Regex-Engine festlegen. Normalerweise können Sie dies erreichen, indem Sie dem regulären Ausdruck voranstellen. Dies (?s)
funktioniert jedoch nicht in allen regulären Ausdrucksmodulen (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 von a ?
zum *
Quantifizierer wird versucht, so wenige Zeichen wie möglich von der aktuellen Position abzugleichen:
.*?(?=(?:X)|$)
stimmt mit einer beliebigen Anzahl von Zeichen überein und stoppt unmittelbar vor X
(dies kann ein beliebiger regulärer Ausdruck sein) oder dem Ende der Zeichenfolge (falls X
dies nicht übereinstimmt). Möglicherweise müssen Sie auch die Option "Punkt stimmt mit allen überein" festlegen, damit dies funktioniert. (Hinweis: Ich habe eine nicht erfassende Gruppe hinzugefügt, um X
sie zuverlässig vom Wechsel zu isolieren.)
(?:...)
nicht erfassenden Gruppe? Funktioniert es mit ((?!X).)*
?
grep
, um Anforderungen für nur eine Datenbank aus MySQL Bin Transformet in SQL zu filtern. Hier ist das Biest:grep -Po "(?s)use database_to_keep(.*?)(?=^use)" mysql-bin.000045.sql > filtered.sql
Up
Taste drücke, ist der letzte Befehl nicht der, den ich verwendet habe:grep -Po "(?s)use database_to_keep(.*?)(?:(?!^use).)*" mysql-bin.000045.sql > filtered.sql
$
Alternative hinzu: Ersetzen Sie .*?(?=X)
durch.*?(?=X|$)
Eine Lookahead-Regex-Syntax kann Ihnen helfen, Ihr Ziel zu erreichen. Somit ist eine Regex für Ihr Beispiel
.*?quick.*?(?=z)
Und es ist wichtig , das zu bemerken , .*?
faul Matching vor dem (?=z)
Look - Ahead: der Ausdruck paßt einen Teil , bis ein erstes Auftreten des z
Briefes.
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
grep
, aber diese Antwort funktioniert.