Регулярное выражение для соответствия подстроки, за которой не следует определенная другая подстрока
Мне нужно регулярное выражение, которое будет соответствовать blahfooblah
но нет blahfoobarblah
Я хочу, чтобы он совпадал только с foo и всем вокруг foo, если за ним не стоит bar.
Я пытался использовать это: foo.*(?<!bar)
что довольно близко, но это соответствует blahfoobarblah
, Отрицательный взгляд должен совпадать с чем угодно, а не только с чертой.
Конкретный язык, который я использую, - это Clojure, который использует регулярные выражения Java под капотом.
РЕДАКТИРОВАТЬ: Более конкретно, мне также нужно, чтобы передать blahfooblahfoobarblah
но нет blahfoobarblahblah
,
5 ответов
Пытаться:
/(?!.*bar)(?=.*foo)^(\w+)$/
тесты:
blahfooblah # pass
blahfooblahbarfail # fail
somethingfoo # pass
shouldbarfooshouldfail # fail
barfoofail # fail
Объяснение регулярного выражения
NODE EXPLANATION
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
bar 'bar'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
.* any character except \n (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
foo 'foo'
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
\w+ word characters (a-z, A-Z, 0-9, _) (1 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
$ before an optional \n, and the end of the
string
Другое регулярное выражение
Если вы хотите исключить bar
когда это сразу после foo
, ты можешь использовать
/(?!.*foobar)(?=.*foo)^(\w+)$/
редактировать
Вы сделали обновление своего вопроса, чтобы сделать его конкретным.
/(?=.*foo(?!bar))^(\w+)$/
Новые тесты
fooshouldbarpass # pass
butnotfoobarfail # fail
fooshouldpassevenwithfoobar # pass
nofuuhere # fail
Новое объяснение
(?=.*foo(?!bar))
обеспечивает foo
найден, но не отслеживается напрямую bar
Чтобы соответствовать foo
после чего-то, что не начинается с bar
, пытаться
foo(?!bar)
Ваша версия с негативным взглядом сзади "соответствует foo
сопровождается чем-то, что не заканчивается bar
". .*
соответствует всем barblah
и (?<!bar)
оглядывается на lah
и проверяет, что это не соответствует bar
, чего нет, поэтому весь шаблон совпадает.
Вместо этого используйте отрицательный взгляд вперед:
\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*
Это сработало для меня, надеюсь, это поможет. Удачи!
Вы написали комментарий, предлагающий, чтобы вы работали так, чтобы соответствовать всем словам в строке, а не самой строке.
Вместо того, чтобы смешивать все это в комментарии, я публикую это как новый ответ.
Новый Регекс
/(?=\w*foo(?!bar))(\w+)/
Пример текста
Что бы там ни было, да и вообще, не так, как здесь.
Матчи
фоусбар
Ваш конкретный запрос на совпадение может быть сопоставлен:
\w+foo(?!bar)\w+
Это будет соответствовать blahfooblahfoobarblah
но нет blahfoobarblahblah
,
Проблема с вашим регулярным выражением foo.*(?<!bar)
это .*
после foo
, Он соответствует какому-либо количеству любых символов, включая символы после bar
,