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).


Und welches spezifische Muster möchten Sie nicht anpassen?
Dominic Rodger

2
Gibt es einen Grund, warum Sie nicht mit Ihrem Muster übereinstimmen und nichts tun können, wenn die Zeichenfolge dem entspricht?
Thomas Owens


@ 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.


7
Verwenden Sie mit grep -P, um Lookahead zu aktivieren.
Seppo Enarvi

Wenn Sie nicht mit "foo" oder "bar" übereinstimmen
möchten

15
Diese Antwort ist falsch, ein schneller Test zeigt das. Ich denke, was Sie gemeint haben, ist ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
Gilad Mayani

4
Könnten Sie bitte erklären, welche Symbole Sie verwendet haben und warum Sie sie verwendet haben?
Rotimi-Best

339

Regex: alles zusammenpassen, aber :

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.

[^=]*

wird alles passen aber =


55
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.


Vielleicht geschrieben str !~ /\Aindex\.php/.
Cary Swoveland

6

In Python:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

3
Das wird "index_php" oder "index # php" ablehnen.

1

Ich brauche eine Regex Lage, alles paßt aber ausnehmen eine Zeichenfolge , beginnend mit index.php einem bestimmten Muster (insbesondere index.php und was folgt, wie index.php? Id = 2342343)

Verwenden Sie die Methode Exec

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

ODER ANDERES SPIEL

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);


-13

Wie wäre es, wenn Sie keinen regulären Ausdruck verwenden:

// In PHP
0 !== strpos($string, 'index.php')

11
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
regulären Ausdruck
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.