регулярное выражение для соответствия string1, если не предшествует string2 - PullRequest
15 голосов
/ 31 июля 2009

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

Ответы [ 5 ]

34 голосов
/ 31 июля 2009

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

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

3 голосов
/ 31 июля 2009

Отрицательный просмотр не поддерживается до 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"]
2 голосов
/ 31 июля 2009

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

/[^x](y)/
0 голосов
/ 31 июля 2009

Это можно сделать с негативным взглядом позади, (?<!x)y

0 голосов
/ 31 июля 2009

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

(:<!x)y

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

...