регулярное выражение для соответствия string1, если не предшествует строка 2
-
06-07-2019 - |
Вопрос
Используя Ruby, как я могу использовать одно регулярное выражение для сопоставления всех вхождений 'y' в " xy y ay xy + y " которым НЕ предшествует x (y, ay, + y)?
/ [^ x] y / также соответствует предыдущему символу, поэтому мне нужен альтернативный вариант ...
Решение
Вам нужно отрицательное утверждение с нулевой шириной. Попробуйте /(?<!x)y/
, который говорит именно то, что вы ищете, то есть найдите все «y», за которыми не стоит «x», но не включает предшествующий символ, который является частью нулевой ширины.
Отредактировано для добавления: Очевидно, это поддерживается только в Ruby 1.9 и выше.
Другие советы
Отрицательный просмотр не поддерживается до Ruby 1.9, но вы можете сделать что-то подобное, используя scan:
"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"]
Ruby, к сожалению, не поддерживает отрицательный внешний вид, поэтому у вас будут проблемы, если вам нужно искать больше, чем один символ. Только для одного персонажа вы можете позаботиться об этом, захватив совпадение:
/[^x](y)/
В PCRE вы используете негативный взгляд:
(:<!x)y
Не уверен, что это поддерживается Ruby, но вы всегда можете посмотреть.
Это можно сделать с негативным взглядом позади, (?<!x)y