2009-07-31 6 views
15

Mit Ruby, wie kann ich eine einzige Regex verwenden, um alle Vorkommen von 'y' in "xy y ay xy + y" zu finden, denen NICHT x vorangestellt ist (y, ay, + y)?
/[^ x] y/passt zu den vorhergehenden Zeichen, also brauche ich eine Alternative ...regexp um mit string1 übereinzustimmen, außer mit string2

+0

Ich wollte eine negative Lookbehind vorschlagen, aber es sieht aus wie Sie aus Glück in dieser Hinsicht sind: http://www.regular-expressions.info /lookaround.html#limitbehind. * "Flavors wie JavaScript, Ruby und Tcl unterstützen Lookhind überhaupt nicht, obwohl sie Lookahead unterstützen." * –

+0

Siehe auch http://StackOverflow.com/questions/530441/how-would-you-use- a-regular-expression-to-ignore-strings-das-enthält-eine-spezifische – finnw

+0

Wenn Look-Back-Assertions nicht unterstützt werden, könnten wir folgendes verwenden: '([^ x] y") | (^ y ")' . 'y' könnte am Anfang des Strings stehen und dieser Fall wird nicht von '/ [^ x] y /' abgedeckt. – approxiblue

Antwort

34

Sie benötigen eine Negative-Look-Behind-Assertion mit einer Breite von Null. Versuchen Sie /(?<!x)y/, die genau sagt, wonach Sie suchen, d. H. Finden Sie alle 'y' nicht vor 'x', aber nicht das vorherige Zeichen, das ist die Null-Breite Teil.

Bearbeitet hinzuzufügen: Anscheinend wird dies nur von Ruby 1.9 und höher unterstützt.

-1

In PCRE, verwenden Sie einen negativen Blick hinter:

(:<!x)y 

Nicht sicher, ob dies unterstützt von Ruby, aber Sie können immer nachschlagen.

-1

Es kann hinter mit negativem Blick erfolgen, (?<!x)y

2

Rubin leider nicht negativ Lookbehind nicht unterstützt, so dass Sie Probleme haben, wenn Sie mehr als ein einzelnes Zeichen zu suchen. Für nur einen Charakter, können Sie sich darum kümmern, indem das Spiel erfassen:

/[^x](y)/ 
+0

Ah, ich bin kein Ruby-Experte - jbourque sagt negative Lookbehind ist in neueren Ruby. Da ist deine echte Antwort. – Cascabel

+0

[^ x] muss mit einem Zeichen übereinstimmen. Wenn y am Anfang der Zeile vorkommt, sollten wir es anpassen:/(?: \ A |^| [^ x]) y / –

3

Negativen Blick hinter bis Ruby nicht 1.9 unterstützt, aber Sie können etwas ähnliches mit Scan tun:

"xy y ay xy +y".scan(/([^x])(y)/) # => [[" ", "y"], ["a", "y"], ["+", "y"]] 
"xy y ay xy +y".scan(/([^x])(y)/).map {|match| match[1]} # => ["y", "y", "y"] 

Das ist natürlich viel schwieriger, wenn Sie viel mehr als ein einzelnes Zeichen vor dem y vermeiden wollen. Dann würden Sie haben so etwas wie zu tun:

"abby y crabby bally +y".scan(/(.*?)(y)/).reject {|str| str[0] =~ /ab/} # => [[" ", "y"], [" ball", "y"], [" +", "y"]] 
"abby y crabby bally +y".scan(/(.*?)(y)/).reject {|str| str[0] =~ /ab/}.map {|match| match[1]} # => ["y", "y" "y"] 
Verwandte Themen