Ein regulärer Ausdruck zum Ausschließen eines Wortes / einer Zeichenfolge

298

Ich habe einen regulären Ausdruck wie folgt:

^/[a-z0-9]+$

Dies entspricht Zeichenfolgen wie /hellooder /hello123.

Ich möchte jedoch, dass einige Zeichenfolgenwerte wie /ignoremeund ausgeschlossen werden /ignoreme2.

Ich habe ein paar Varianten ausprobiert, kann aber anscheinend keine zum Laufen bringen!

Mein letzter schwacher Versuch war

^/(((?!ignoreme)|(?!ignoreme2))[a-z0-9])+$

Jede Hilfe wäre dankbar :-)

romiem
quelle
1
Mögliches Duplikat: stackoverflow.com/questions/1395177/…
Anderson Green

Antworten:

376

Hier ist noch ein anderer Weg (mit einem negativen Ausblick ):

^/(?!ignoreme|ignoreme2|ignoremeN)([a-z0-9]+)$ 

Hinweis: Es gibt nur einen Erfassungsausdruck : ([a-z0-9]+).

Seth
quelle
1
Genial, das scheint den Trick getan zu haben. Ich brauche diese Regel tatsächlich zum Umschreiben von URLs und wollte die Ordner "images", "css" und "js" ignorieren. Meine Regel lautet also wie folgt: ^ / (?! Css | js | images) ([az] +) /? (\? (. +))? $ Und es wird in /Profile.aspx?id=$1&$3 umgeschrieben Funktioniert diese Regel ordnungsgemäß und gibt auch die Abfragezeichenfolge weiter? Wenn also jemand mydomain.com/hello?abc=123 besucht, möchte ich, dass es in mydomain.com/Profile.aspx?id=hello&abc=123 umgeschrieben wird. Ich bin mir auch ein bisschen unsicher über die Leistung von (. +) Bei das Ende, um den Querystring in der ursprünglichen Anforderung zu erfassen.
Romiem
Klingt so, ist eine andere Frage. Der reguläre Ausdruck, den Sie haben, erfasst die Abfragezeichenfolge - testen Sie, ob Ihre Abfragezeichenfolge vorhanden ist. Auch - (\?(.+))?$sollte schnell sein. Ich würde mir keine Sorgen um die Geschwindigkeit machen.
Seth
1
Dies hat bei mir nicht funktioniert, während die Lösung von Alix Axel funktioniert hat. Ich benutze Javas java.util.regex.PatternKlasse.
Mark Jeronimus
1
Ich bestätige Marks reMark;) - zum Beispiel ist Pycharm Java-basiert, nicht wahr? Wenn man bedenkt, dass Regexe in der Pycharm-Suche funktionieren, funktioniert die Lösung von Alix, die andere nicht.
Fanny
43

Dies sollte es tun:

^/\b([a-z0-9]+)\b(?<!ignoreme|ignoreme2|ignoreme3)

Sie können so viele ignorierte Wörter hinzufügen, wie Sie möchten. Hier ist eine einfache PHP-Implementierung:

$ignoredWords = array('ignoreme', 'ignoreme2', 'ignoreme...');

preg_match('~^/\b([a-z0-9]+)\b(?<!' . implode('|', array_map('preg_quote', $ignoredWords)) . ')~i', $string);
Alix Axel
quelle
Ich dachte, Look-Behind erfordert ein Muster mit fester Breite?
Simon
2
@AlixAxel Dies ist der Fall, aber intelligentere Regex-Bibliotheken ermöglichen eine Abwechslung mit unterschiedlichen Längen für die Alternativen (und verwenden die längste), sofern jede Alternative eine feste Länge hat.
ChrisF
Das ist klug, schlägt aber für mich fehl, wenn das ignorierte Wort am Ende eines anderen Wortes steht. dh wenn Sie 'a' als eines der ignorierten Wörter hinzufügen, wird jedes Wort, das mit a endet, ignoriert
singmotor
21

Da Sie beide Wörter ausschließen möchten, benötigen Sie eine Konjunktion:

^/(?!ignoreme$)(?!ignoreme2$)[a-z0-9]+$

Jetzt müssen beide Bedingungen erfüllt sein (weder ignoreme noch ignoreme2 dürfen), um eine Übereinstimmung zu haben.

Gumbo
quelle
1
Dies entspricht dem kürzeren oben, der einen negativen Lookahead einer Reihe von Alternativen darstellt.
ChrisF
4
@ ChrisF Nein, nicht wirklich. Seths Lösung würde nicht mit so etwas wie /ignoremenotder /folgenden übereinstimmen ignoreme.
Gumbo