Regexp для соответствия string1, если не указано значение string2

Используя Ruby, как я могу использовать одно регулярное выражение для соответствия всем вхождениям "y" в "xy y ay xy + y", которым НЕ предшествует x (y, ay, + y)?
/[^ x] y/соответствует предыдущему символу, поэтому мне нужна альтернатива...

Ответы

Ответ 1

Вам нужно подтверждение отрицательной обратной связи с нулевой шириной. Попробуйте /(?<!x)y/, в котором указано именно то, что вы ищете, т.е. Найдите все "y", не предшествующие "x", но не включите предшествующий символ, который является частью нулевой ширины.

Отредактировано для добавления: По-видимому, это поддерживается только с Ruby 1.9 и выше.

Ответ 2

Отрицательный внешний вид не поддерживается до Ruby 1.9, но вы можете сделать что-то подобное с помощью сканирования:

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

Конечно, это намного сложнее, если вы хотите избежать намного большего, чем один символ перед y. Тогда вам нужно будет сделать что-то вроде:

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

Ответ 3

Ruby, к сожалению, не поддерживает отрицательный lookbehind, поэтому у вас возникнут проблемы, если вам нужно искать больше одного персонажа. Для одного персонажа вы можете позаботиться об этом, взяв совпадение:

/[^x](y)/

Ответ 4

В PCRE вы используете отрицательный внешний вид:

(:<!x)y

Не уверен, что это поддерживается Ruby, но вы всегда можете поискать.

Ответ 5

Это можно сделать с отрицательным внешним видом, (?<!x)y