2013-08-14 12 views
10

Ich habe die folgenden Muster ausgeschlossen werden.RegEx - Matched Muster ausschließen

make it cheaper 
make it cheapere 
makeitcheaper.com.au 
makeitcheaper 
making it cheaper 
www.make it cheaper 
ww.make it cheaper.com 

Ich habe eine Regex erstellt, um alle diese anzupassen. Ich möchte jedoch alles andere als diese bekommen. Ich bin mir nicht sicher, wie ich diese Regex, die ich erstellt habe, umkehren kann.

mak(e|ing) ?it ?cheaper 

Das obige Muster stimmt mit allen aufgelisteten Strings überein. Jetzt möchte ich, dass es zu allem anderen passt. Wie mache ich es?

Von der Suche scheint es, ich brauche etwas wie negative Lookahead/Look Back. Aber ich verstehe es nicht wirklich. Kann mir jemand in die richtige Richtung zeigen?

Antwort

17

Sie können wie so in einem negativen Vorgriff legen du es einfach:

(?!mak(e|ing) ?it ?cheaper) 

Genau wie das nicht obwohl, da funktionieren werden, wenn Sie ein matches tun, wird es nicht passen Sie an, da Sie nur vorausschauend sind, stimmen Sie nichts wirklich überein, und wenn Sie eine find machen, wird es viele Male übereinstimmen, da Sie von vielen Stellen in der Zeichenfolge beginnen können, wo die nächsten Zeichen doesn nicht mit den oben genannten übereinstimmen.

Um dies zu beheben, je nachdem, was Sie tun wollen, haben wir 2 Möglichkeiten:

  1. Wenn Sie alle Strings ausschließen möchten, die genau einer von denen, (dh „machen es cheaperblahblah“ sind nicht ausgeschlossen ist), überprüfen Sie Start (^) und Ende ($) von string:

    ^(?!mak(e|ing) ?it ?cheaper$).* 
    

    die .* (null oder mehr Wildcards) stattfindet, die tatsächliche Anpassung ist. Die negative Vorausschau wird vom ersten Zeichen überprüft.

  2. Wenn Sie alle Strings ausschließen mögen einen von denen, enthalten, können Sie sicherstellen, dass der Vorgriff abgestimmt ist nicht vor jedem Charakter, den wir entsprechen:

    ^((?!mak(e|ing) ?it ?cheaper).)*$ 
    

    Eine Alternative ist wild hinzufügen -Karten an den Anfang Ihrer Vorausschau (d. hSchließen Sie alle Zeichenfolgen aus, die vom Anfang der Zeichenfolge an etwas enthalten, dann Ihr Muster), aber ich sehe derzeit keinen Vorteil darin (die Suche nach beliebiger Länge wird wahrscheinlich auch von einem bestimmten Werkzeug nicht unterstützt):

    ^(?!.*mak(e|ing) ?it ?cheaper).* 
    

Wegen der ^ und $, entweder macht ein find oder ein matches wird für eine der oben arbeiten (obwohl im Fall von matches ist die ^ optional und, im Fall von find, die .* außerhalb der Vorausschau ist optional).


1: Obwohl sie nicht genannt werden kann, dass viele Sprachen haben äquivalente Funktionen zu matches und find mit regex.


Das obige ist die strictly-regex Antwort auf diese Frage.

Ein besserer Ansatz könnte darin bestehen, sich an den Originalregex (mak(e|ing) ?it ?cheaper) zu halten und zu sehen, ob Sie die Übereinstimmungen direkt mit dem verwendeten Werkzeug oder der Sprache negieren können.

In Java würde dies zum Beispiel if (!string.matches(originalRegex)) (beachten Sie die !, die den zurückgegebenen booleschen Wert negiert) statt if (string.matches(negLookRegex)) tun.

6

Der negative Lookahead, ich glaube, was Sie suchen. Vielleicht versuchen:

(?!.*mak(e|ing) ?it ?cheaper) 

Und vielleicht ein bisschen flexibler:

(?!.*mak(e|ing) *it *cheaper) 

Nur für den Fall gibt es mehr als ein Raum.