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