2010-05-14 19 views
13

Diese interessante Frage Regex to match anything (including the empty string) except a specific given string besorgt, wie man eine negative Vorausschau in MySQL macht. Das Plakat, welches die Wirkung vonWie konvertiert man eine PCRE zu einer POSIX RE?

Kansas(?! State)

bekommen wollte, weil MySQL nicht Vorgriff Behauptungen umzusetzen, kam eine Reihe von Antworten auf das äquivalente

Kansas($|[^ ]| ($|[^S])| S($|[^t])| St($|[^a])| Sta($|[^t])| Stat($|[^e]))

Das Plakat wies darauf hin, das ist ein PITA für potenziell viele Ausdrücke.

Gibt es ein Skript/Dienstprogramm/Modus von PCRE (oder einem anderen Paket), das ein PCRE (wenn möglich) in einen äquivalenten Regex konvertiert, der nicht die pfiffigen Funktionen von Perl verwendet? Ich bin mir völlig bewusst, dass einige Perl-Regex nicht als normale Regex bezeichnet werden können, also würde ich nicht erwarten, dass das Tool das Unmögliche möglich macht!

+0

Vor Jahren habe ich ein Werkzeug zum Umwandeln eines Regex in ein NFA oder DFA und zurück zu einem Regex gesehen, aber ich kann es jetzt nicht finden. Dieses Werkzeug erlaubte eine Überschneidung und Ergänzung in Eingabe-Regexes, und IIRC die rekonstruierte Regex verwendete diese Konstrukte nicht. –

+15

Es ist erwähnenswert, dass die beiden regulären Ausdrücke in der Frage nicht exakt gleichwertig sind: Obwohl beide im ursprünglichen Beispiel dasselbe tun, verhalten sie sich unter bestimmten Umständen unterschiedlich. Zum Beispiel, wenn in einer Substitution verwendet (z. B. Ersetzen von "Kansas" durch "Home" in der Zeichenfolge "Kansas Starbucks"), die erste gibt "Home Starbucks", während die zweite "Homebucks" geben wird. In dieser Hinsicht ist es nicht möglich, einen regulären POSIX-Regressionsausdruck zu verwenden, der genau das negative Vorausschauverhalten nachahmt. – psmears

Antwort

2

Sie möchten dies nicht tun. Es ist nicht wirklich unglaublich schwierig, die fortgeschrittenen Funktionen in grundlegende Funktionen zu übersetzen - es ist nur ein anderer Geschmack des Compilers, und Compiler-Schreiber sind ziemlich clevere Leute - aber die meisten Dinge, die die pfiffigen Funktionen lösen, sind (a) unmöglich mit a zu tun Standard-Regex, weil sie nicht-reguläre Sprachen erkennen, also müssten Sie sie approximieren, so dass sie zumindest für einen Text begrenzter Länge oder (b) möglich sind, aber nur mit einem Regex exponentieller Größe. Und "exponentiell" ist ein Kompromiss für "geh nicht dorthin". Sie wird in OutOfMemory Fehler und scheinbar unendliche Schleifen überschwemmt werden, wenn Sie versuchen, eine exponentielle Lösung für alles zu verwenden, was Sie tatsächlich verarbeiten möchten.

In anderen Worten, alle Hoffnung aufgeben, die, die hier eintreten. Es ist praktisch immer besser, wenn der Regex das tut, was er kann und den Rest mit anderen Werkzeugen erledigt. Sogar eine so einfache Sache wie das Invertieren einer Regex wird viel einfacher mit der ursprünglichen Regex in Kombination mit dem Negationsoperator gelöst als mit der Monstrosität, die sich aus einem genauen Regex-Inverter ergeben würde.

Verwandte Themen