Мне нужен regex, который будет соответствовать blahfooblah
но нет blahfoobarblah
Я хочу, чтобы это соответствовало только нечто и всему вокруг нечто, пока это не сопровождается панелью.
Я пытался использовать это: foo.*(?<!bar)
который довольно близок, но это соответствует blahfoobarblah
. Отрицательный взгляд позади потребностей соответствовать чему-либо и не просто панели.
Определенным языком, который я использую, является Clojure, который использует Java regexes под капотом.
Править: Строго говоря, мне также нужен он для передачи blahfooblahfoobarblah
но нет blahfoobarblahblah
.
/(?!.*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
, а (? смотрит назад на
lah
и проверяет, что это не ' t соответствует bar
, чего нет, поэтому соответствует весь шаблон.
Вместо этого используйте негативный взгляд вперед:
\s*(?!\w*(bar)\w*)\w*(foo)\w*\s*
Это сработало для меня, надеюсь, что это помогает. Удачи!
Ваш конкретный запрос на сопоставление может быть сопоставлен с помощью:
\w+foo(?!bar)\w+
Это будет соответствовать blahfooblahfoobarblah
, но не blahfoobarblahblah
.
Проблема с вашим регулярным выражением foo. * (? - это
. *
после foo
. Он соответствует как можно большему количеству любых символов, включая символы после bar
.
Вы написали комментарий, предполагающий, что вам нравится это, чтобы работать со сопоставлением всех слов в строке, а не всей строки.
Вместо того, чтобы смешивать все это в комментарии, я публикую это как новый ответ.
/(?=\w*foo(?!bar))(\w+)/
foowithbar fooevenwithfoobar notfoobar foohere notfoobarhere butfooisokherebar notfoobarhere andnofuu needsfoo
foowithbar fooevenwithfoobar foohere butfooisokherebar needsfoo