So verwenden Sie PCRE's Backtracking-Steuerungsverben, um eine Zeile ohne ein Wort abzugleichen
Hier ist eine Methode, die ich noch nicht gesehen habe:
/.*hede(*COMMIT)^|/
Wie es funktioniert
Zuerst versucht es, "hede" irgendwo in der Zeile zu finden. Wenn erfolgreich, sagt (*COMMIT)
dem Motor, nicht nur im Falle eines Fehlers nicht zurückzuverfolgen, sondern auch keine weiteren Übereinstimmungen in diesem Fall zu versuchen. Dann versuchen wir, etwas abzugleichen, das unmöglich übereinstimmen kann (in diesem Fall ^
).
Wenn eine Zeile "hede" nicht enthält, trifft die zweite Alternative, ein leeres Teilmuster, erfolgreich auf den Zeichenfolge zu.
Diese Methode ist nicht effizienter als ein negativer Ausblick, aber ich dachte, ich werde sie hier einfach hinschmeißen, falls jemand sie hübsch findet und eine Verwendung dafür in anderen, interessanteren Anwendungen findet.
108 Stimmen
Wahrscheinlich ein paar Jahre zu spät, aber was ist falsch mit:
([^h]*(h([^e]|$)|he([^d]|$)|hed([^e]|$)))*
? Die Idee ist einfach. Fahren Sie mit dem Abgleich fort, bis Sie den Beginn des unerwünschten Strings sehen, und gleichen Sie dann nur in den N-1 Fällen ab, in denen der String nicht abgeschlossen ist (wobei N die Länge des Strings ist). Diese N-1 Fälle sind "h gefolgt von nicht-e", "he gefolgt von nicht-d" und "hed gefolgt von nicht-e". Wenn es Ihnen gelungen ist, diese N-1 Fälle zu bestehen, haben Sie den unerwünschten String erfolgreich nicht abgeglichen, sodass Sie erneut mit der Suche nach[^h]*
beginnen können.441 Stimmen
@stevendesu: Versuche dies für 'ein-sehr-sehr-langes-Wort' oder noch besser einen halben Satz. Viel Spaß beim Tippen. Übrigens, es ist fast unleserlich. Weiß nicht über den Leistungseinfluss.
14 Stimmen
@PeterSchuetze: Sicher ist es nicht schön für sehr sehr lange Wörter, aber es ist eine praktikable und korrekte Lösung. Obwohl ich keine Tests zur Leistung durchgeführt habe, würde ich mir vorstellen, dass es nicht allzu langsam ist, da die meisten nachfolgenden Regeln ignoriert werden, bis Sie ein h sehen (oder den ersten Buchstaben des Wortes, Satzes usw. sehen). Und Sie könnten den Regex-String für lange Zeichenfolgen leicht mithilfe iterativer Konkatenation generieren. Wenn es funktioniert und schnell generiert werden kann, ist Lesbarkeit wichtig? Dafür sind Kommentare da.
66 Stimmen
@stevendesu: Ich bin noch später dran, aber diese Antwort ist fast komplett falsch. Zum einen verlangt sie, dass das Subjekt "h" enthält, was es nicht sollte, da die Aufgabe lautet, "Zeilen abzugleichen, die ein bestimmtes Wort nicht enthalten". Lassen Sie uns annehmen, dass Sie die innere Gruppe optional machen wollten und dass das Muster verankert ist:
^([^h]*(h([^e]|$)|he([^d]|$)|hed([^e]|$))?)*$
. Dies scheitert, wenn Instanzen von "hede" von teilweisen Instanzen von "hede" wie in "hhede" vorausgehen.22 Stimmen
Diese Frage wurde zum Stack Overflow Regular Expression FAQ hinzugefügt, unter "Advanced Regex-Fu".
0 Stimmen
Verwandt: Regex: Übereinstimmung durch Ausschluss, ohne Vorwärtsblick - ist das möglich?