Regex: Passen Sie alles außer einem bestimmten Muster an
310
Ich brauche eine Regex, die in der Lage ist, alles außer einer Zeichenfolge abzugleichen, die mit einem bestimmten Muster beginnt (speziell index.phpund wie folgt index.php?id=2342343).
@ ThomasOwens: Es kommt darauf an. Es kommt darauf an, welcher Teil des Ausdrucks negiert werden soll. Wenn der gesamte Ausdruck negiert werden soll, haben Sie einen Punkt. Wenn Sie beispielsweise "Wenn die Zeichenfolge nicht 'Bruce' als Teilzeichenfolge enthält, dann tun Sie etwas" codieren möchten, verwenden Sie einfach / Bruce / und setzen die Negation in die if-Anweisung außerhalb des regulären Ausdrucks . Es kann aber auch sein, dass Sie einen Unterausdruck negieren möchten. Angenommen, Sie suchen nach etwas wie Vorname Nachname, wobei Vorname Bruce ist, und Nachname ist alles außer XYZ, wo XYZ der Nachname einer Berühmtheit namens Bruce ist.
Mathheadinclouds
Antworten:
250
Kein Regexp-Experte, aber ich denke, Sie könnten von Anfang an einen negativen Lookahead verwenden, z. B. ^(?!foo).*$sollte nichts mit dem übereinstimmen foo.
Andere Engines, die Lookarounds zulassen: (cat)|[^c]*(?:c(?!at)[^c]*)*(oder (?s)(cat)|(?:(?!cat).)*, oder (cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*) und dann mit der Sprache prüfen, bedeuten: Wenn Gruppe 1 übereinstimmt, ist dies nicht das, was wir benötigen. Andernfalls greifen Sie auf den Übereinstimmungswert zu, wenn er nicht leer ist
ein bestimmtes einzelnes Zeichen oder eine Reihe von Zeichen :
Demo-Hinweis : Die neue Zeile \nwird in negierten Zeichenklassen in Demos verwendet, um einen Überlauf der Übereinstimmungen mit den benachbarten Zeilen zu vermeiden. Sie sind beim Testen einzelner Zeichenfolgen nicht erforderlich.
Ankerhinweis : Verwenden Sie in vielen Sprachen \Aden eindeutigen Anfang der Zeichenfolge und \z(in Python ist es \Zin JavaScript $OK), um das Ende der Zeichenfolge zu definieren.
Punktnotiz : In vielen Geschmacksrichtungen (aber nicht POSIX, TRE, TCL) .passt jedes Zeichen außer einem Zeilenumbruchzeichen . Stellen Sie sicher, dass Sie einen entsprechenden DOTALL-Modifikator ( /sin PCRE / Boost / .NET / Python / Java und /min Ruby) verwenden ., damit alle Zeichen einschließlich eines Zeilenumbruchs übereinstimmen.
Backslash Anmerkung : In Sprachen , in denen Sie Muster mit C - Strings deklarieren müssen damit Escape - Sequenzen (wie \nfür eine neue Zeile), müssen Sie die Schrägstriche zu entkommen Sonderzeichen so verdoppeln , dass der Motor sich als normale Zeichen behandeln könnte (zB in Java, world\.wird deklariert als "world\\."oder eine Zeichenklasse verwenden :) "world[.]". Verwenden Sie rohe String-Literale (Python r'\bworld\b'), wörtliche C # @"world\."-String- Literale oder Slash-Strings / Regex-Literal-Notationen wie /world\./.
Tolles Schreiben! Für den Fall "eine Zeichenfolge (nicht) gleich einer Zeichenfolge", am Beispiel von ^(?!foo$), warum muss das Dollarzeichen in Klammern stehen, damit der Ausdruck funktioniert? Ich hatte erwartet ^(?!foo)$, die gleichen Ergebnisse zu erzielen, aber das tut es nicht.
Grant Humphries
3
@GrantHumphries: Wenn sich der $Anker innerhalb des Lookaheads befindet, ist er Teil der Bedingung, Teil dieser Behauptung mit der Breite Null . Wenn es außerhalb wie in wäre ^(?!foo)$, wäre es Teil des konsumierenden Musters, das das Ende der Zeichenfolge direkt nach dem Beginn der Zeichenfolge erfordert, wodurch der negative Lookahead irrelevant wird, da er immer true zurückgeben würde (nach dem Ende der Zeichenfolge darf kein Text mehr vorhanden sein) geschweige denn foo). Entspricht also dem ^(?!foo$)Anfang einer Zeichenfolge, auf die nicht folgt foo, und dem Zeichenfolgenende. ^(?!foo)$stimmt mit einer leeren Zeichenfolge überein.
Wiktor Stribiżew
@ robots.txt Bitte entfernen Sie diese Kommentare. Sie stellen eine XY-Frage. Zeichenklassen sollen mit einzelnen Zeichen übereinstimmen. Es gibt keine Möglichkeit, eine Zeichenfolge mit ihnen zu definieren. Sie sollten wahrscheinlich nur die Teilzeichenfolge zwischen dem Beginn eines Strings und dem ersten Auftreten von cotoder lanfinden und die Übereinstimmung entfernen, wie z regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Wiktor Stribiżew
Lieber Wiktor. Sie haben meine Frage geschlossen, aber Ihre verknüpfte Antwort schlägt fehl. Ich habe meine Frage stackoverflow.com/questions/60004380/…
MonsterMMORPG
Zum Beispiel schlägt Ihre verknüpfte Antwort in diesem Beispiel fehl. "Die Editoren für Pakete <! - und Webseiten <! - asdasasdas -> verwenden jetzt -> Lorem Ipsum"
MonsterMMORPG
259
Sie können ein ^am Anfang eines Zeichensatzes einfügen, damit alles andere als diese Zeichen übereinstimmen.
Das stimmt, aber es wird jeweils nur ein Zeichen verarbeitet. Wenn Sie eine Folge von zwei oder mehr Zeichen ausschließen möchten, müssen Sie einen negativen Lookahead verwenden, wie die anderen Antwortenden sagten.
Alan Moore
perfekte Lösung, um unerwünschte Zeichen außer denen im Muster zu entfernen . danke
Sirmyself
@Alan, "... du musst einen negativen Lookahead verwenden ..." ist falsch, aber wir sollten nicht zu hart für dich sein, weil Wiktor seine Antwort nicht veröffentlicht hat - was zeigt, warum - bis 2016.
Cary Swoveland
6
Einfach übereinstimmen, /^index\.php/dann ablehnen, was auch immer passt.
Ich brauche eine Regex Lage, alles paßt aber ausnehmen eine Zeichenfolge , beginnend mitindex.php einem bestimmten Muster (insbesondere index.php und was folgt, wie index.php? Id = 2342343)
Das OP hat ausdrücklich eine Regex angefordert ... Ich bin mir nicht sicher, ob dies hilft! (Er verwendet möglicherweise beispielsweise grepdie Befehlszeile oder Perl / Python / eine andere Sprache oder den Befehl "Diesen
Antworten:
Kein Regexp-Experte, aber ich denke, Sie könnten von Anfang an einen negativen Lookahead verwenden, z. B.
^(?!foo).*$
sollte nichts mit dem übereinstimmenfoo
.quelle
^((?!foo).)*$
( stackoverflow.com/a/406408/3964381 )Regex: alles zusammenpassen, aber :
foo
):^(?!foo).*$
^(?!foo)
^(([^f].{2}|.[^o].|.{2}[^o]).*|.{0,2})$
^([^f].{2}|.[^o].|.{2}[^o])|^.{0,2}$
world.
am Ende):(?<!world\.)$
^.*(?<!world\.)$
^(.*([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.])|.{0,5})$
([^w].{5}|.[^o].{4}|.{2}[^r].{3}|.{3}[^l].{2}|.{4}[^d].|.{5}[^.]$|^.{0,5})$
foo
) (kein POSIX-kompatibles Muster, sorry):^(?!.*foo)
^(?!.*foo).*$
|
Symbol abzugleichen):^[^|]*$
foo
):^(?!foo$)
^(?!foo$).*$
^(.{0,2}|.{4,}|[^f]..|.[^o].|..[^o])$
cat
):/cat(*SKIP)(*FAIL)|[^c]*(?:c(?!at)[^c]*)*/i
oder/cat(*SKIP)(*FAIL)|(?:(?!cat).)+/is
(cat)|[^c]*(?:c(?!at)[^c]*)*
(oder(?s)(cat)|(?:(?!cat).)*
, oder(cat)|[^c]+(?:c(?!at)[^c]*)*|(?:c(?!at)[^c]*)+[^c]*
) und dann mit der Sprache prüfen, bedeuten: Wenn Gruppe 1 übereinstimmt, ist dies nicht das, was wir benötigen. Andernfalls greifen Sie auf den Übereinstimmungswert zu, wenn er nicht leer ist[^a-z]+
(ein anderes Zeichen als ein ASCII-Kleinbuchstabe)|
:[^|]+
Demo-Hinweis : Die neue Zeile
\n
wird in negierten Zeichenklassen in Demos verwendet, um einen Überlauf der Übereinstimmungen mit den benachbarten Zeilen zu vermeiden. Sie sind beim Testen einzelner Zeichenfolgen nicht erforderlich.Ankerhinweis : Verwenden Sie in vielen Sprachen
\A
den eindeutigen Anfang der Zeichenfolge und\z
(in Python ist es\Z
in JavaScript$
OK), um das Ende der Zeichenfolge zu definieren.Punktnotiz : In vielen Geschmacksrichtungen (aber nicht POSIX, TRE, TCL)
.
passt jedes Zeichen außer einem Zeilenumbruchzeichen . Stellen Sie sicher, dass Sie einen entsprechenden DOTALL-Modifikator (/s
in PCRE / Boost / .NET / Python / Java und/m
in Ruby) verwenden.
, damit alle Zeichen einschließlich eines Zeilenumbruchs übereinstimmen.Backslash Anmerkung : In Sprachen , in denen Sie Muster mit C - Strings deklarieren müssen damit Escape - Sequenzen (wie
\n
für eine neue Zeile), müssen Sie die Schrägstriche zu entkommen Sonderzeichen so verdoppeln , dass der Motor sich als normale Zeichen behandeln könnte (zB in Java,world\.
wird deklariert als"world\\."
oder eine Zeichenklasse verwenden :)"world[.]"
. Verwenden Sie rohe String-Literale (Pythonr'\bworld\b'
), wörtliche C #@"world\."
-String- Literale oder Slash-Strings / Regex-Literal-Notationen wie/world\./
.quelle
^(?!foo$)
, warum muss das Dollarzeichen in Klammern stehen, damit der Ausdruck funktioniert? Ich hatte erwartet^(?!foo)$
, die gleichen Ergebnisse zu erzielen, aber das tut es nicht.$
Anker innerhalb des Lookaheads befindet, ist er Teil der Bedingung, Teil dieser Behauptung mit der Breite Null . Wenn es außerhalb wie in wäre^(?!foo)$
, wäre es Teil des konsumierenden Musters, das das Ende der Zeichenfolge direkt nach dem Beginn der Zeichenfolge erfordert, wodurch der negative Lookahead irrelevant wird, da er immer true zurückgeben würde (nach dem Ende der Zeichenfolge darf kein Text mehr vorhanden sein) geschweige dennfoo
). Entspricht also dem^(?!foo$)
Anfang einer Zeichenfolge, auf die nicht folgtfoo
, und dem Zeichenfolgenende.^(?!foo)$
stimmt mit einer leeren Zeichenfolge überein.cot
oderlan
finden und die Übereinstimmung entfernen, wie zregex.replace(myString, "^.*?(?:cot|lan)\s*", "")
.Sie können ein
^
am Anfang eines Zeichensatzes einfügen, damit alles andere als diese Zeichen übereinstimmen.wird alles passen aber
=
quelle
Einfach übereinstimmen,
/^index\.php/
dann ablehnen, was auch immer passt.quelle
str !~ /\Aindex\.php/
.In Python:
quelle
Verwenden Sie die Methode Exec
ODER ANDERES SPIEL
quelle
Wie wäre es, wenn Sie keinen regulären Ausdruck verwenden:
quelle
grep
die Befehlszeile oder Perl / Python / eine andere Sprache oder den Befehl "Diesen