2009-07-31 9 views
15

Usando Ruby, ¿cómo puedo usar una sola expresión regular para hacer coincidir todas las apariciones de 'y' en "xy y ay xy + y" que NO van precedidas de x (y, ay, + y)?
/[^ x] y/detecta el carácter anterior también, así que necesito una alternativa ...regexp para que coincida con string1 a menos que esté precedido por string2

+0

que iba a sugerir una búsqueda hacia atrás negativo, pero parece que está fuera de suerte en ese aspecto: http://www.regular-expressions.info /lookaround.html#limitbehind. * "Finalmente, los sabores como JavaScript, Ruby y Tcl no son compatibles con lookbehind en absoluto, a pesar de que admiten el lookahead." * –

+0

Vea también http://stackoverflow.com/questions/530441/how-would-you-use- a-regular-expresión-a-ignorar-cadenas-que-contiene-un-específico – finnw

+0

Si las aserciones de mirada hacia atrás no son compatibles, podríamos usar esto: '([^ x] y") | (^ y ")' . 'y' puede aparecer al comienzo de la cadena y ese caso no está cubierto por '/ [^ x] y /'. – approxiblue

Respuesta

34

Necesita una aserción de observación negativa de ancho cero. Intente /(?<!x)y/, que dice exactamente lo que está buscando, es decir, encuentre toda 'y' no precedida por 'x', pero no incluye el carácter anterior, que es la parte de ancho cero.

Editado para agregar: Aparentemente esto solo es compatible con Ruby 1.9 y posteriores.

-1

En PCRE, se utiliza un vistazo detrás negativo:

(:<!x)y 

No estoy seguro si esto es respaldado por Ruby, pero siempre puedes mirar hacia arriba.

-1

Se puede hacer con un aspecto negativo detrás, (?<!x)y

2

Rubí, lamentablemente no es compatible con búsqueda hacia atrás negativo, por lo que tendrá problemas si necesita buscar más de un solo carácter. Para un solo carácter, que puede hacerse cargo de esta capturando el partido:

/[^x](y)/ 
+0

Ah, no soy un experto en Ruby - jbourque dice que el lookbehind negativo está en Ruby más nuevo. Ahí está tu verdadera respuesta. – Cascabel

+0

[^ x] debe coincidir con un carácter. si y ocurre al comienzo de la línea, debemos hacer coincidirlo:/(?: \ A |^| [^ x]) y / –

3

negativo mirada detrás no se admite hasta Ruby 1.9, pero se puede hacer algo similar con la exploración:

"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"] 

Por supuesto, esto es mucho más difícil si desea evitar mucho más que un solo carácter antes del y. Entonces habría que hacer algo como:

"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"] 
Cuestiones relacionadas