2016-04-30 4 views
3

Ich habe Probleme mit Regex-Lookaheads und alle Tutorials, die ich finden kann, sind für Passwort-Checks und nicht für bestimmte Zeichenkombinationen.Wie entwerfe ich ein Muster, das nur Zeichenfolgen ohne bestimmte Zeichenkombinationen erfasst?

Hier ist ein Problem, das ich nicht verstehe, die mit diesem Teil der Regex mein Kampf beschreibt:

$string1 = 'I have a yellow engine, I have a black engine'; 
$string2 = 'I have a yellow engine, I have a red engine'; 
$string3 = 'I have a red engine, I have a black engine'; 

$pattern = '~I.*?(?!.*(red|green|blue)).*?engine~'; 

$preg_match_all($pattern, $string[1-3], $matches); 

$string1 Matches richtig:

0 => "I have a yellow engine" 
1 => "I have a black engine" 

$string2 passt die gesamte Zeichenfolge und $string3 Matches ähnlich wie $string1.

Wie entwerfe ich ein Muster, das nur Zeichenfolgen erfasst ("Ich habe eine [Farbe] -Engine") ohne bestimmte Farben?

Antwort

2

Die .* nach dem negativen Vorgriff alles passen und tatsächlich die Wirkung des Vorgriffs zerstören. Sie können einfach folgende regex verwenden:

I\s(?:(?!(red|green|blue)).)*engine 

Demo: https://regex101.com/r/tO9nC5/1

Beachten Sie, dass Sie noch nicht .* innerhalb des Vorgriffs brauchen, weil Sie eine * aus ihm haben, die es jeder passen macht Länge der Zeichenfolge.

Beachten Sie auch, dass, wenn Sie Ihre regex verhindern wollen Strings entsprechen wie folgt vor:

I have everything I don't engine 

In der Tat, wenn Sie die innere I vor engine Sie besser passen wollen I auf die Liste der verbotenen Wörter hinzufügen :

I\s(?:(?!(I|red|green|blue)).)*engine 
+2

mit der Erfassung Gruppen: https://regex101.com/r/tO9nC5/2 – AKS

+1

ausgezeichnet, danke! Nichts, was ich versucht habe, hat mich für einige Stunden irgendwo hingebracht, aber das zeigt mir definitiv eine vielversprechende Richtung und regex101 sieht wie ein wunderbares Werkzeug aus. –

-1

Was stimmt nicht einen einfachen Ausdruck wie bei der Verwendung:

I have a * engine 
Verwandte Themen