Регулярное выражение для строки, содержащей одно слово, но не другое

103

Я устанавливаю некоторые цели в Google Analytics и могу использовать небольшую справку по регулярным выражениям.

Допустим, у меня есть 4 URL

http://www.anydotcom.com/test/search.cfm?metric=blah&selector=size&value=1
http://www.anydotcom.com/test/search.cfm?metric=blah2&selector=style&value=1
http://www.anydotcom.com/test/search.cfm?metric=blah3&selector=size&value=1
http://www.anydotcom.com/test/details.cfm?metric=blah&selector=size&value=1

Я хочу создать выражение, которое будет идентифицировать любой URL-адрес, содержащий строку selector = size, но НЕ содержащий details.cfm

Я знаю, что чтобы найти строку, НЕ содержащую другой строки, я могу использовать это выражение:

(^((?!details.cfm).)*$)

Но я не уверен, как добавить в раздел selector = size .

Любая помощь будет принята с благодарностью!

Крис Шталь
источник

Ответы:

144

Это должно сделать это:

^(?!.*details\.cfm).*selector=size.*$

^.*selector=size.*$должно быть достаточно ясно. Первый бит (?!.*details.cfm)- это отрицательный прогноз: перед сопоставлением строки он проверяет, не содержит ли строка "details.cfm" (с любым количеством символов перед ней).

Коби
источник
8
К вашему сведению, посетите regexr.com, чтобы найти хороший способ проверить эти выражения.
Джошуа Пинтер
Всегда забывайте о негативном прогнозе вперед, и это так полезно
Alexei Blue
"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0это неверно. (Обратите внимание, что строка содержит "...selector=sized...".) Кроме того, почему .*$в конце?
Cary Swoveland
4

регулярное выражение может быть (синтаксис perl):

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/`
Джипко
источник
Это поврежденное регулярное выражение, квадратные скобки превращают все последовательности шаблонов в комбинацию отдельных символов.
Wiktor Stribiew
2
^(?=.*selector=size)(?:(?!details\.cfm).)+$

Если ваш механизм регулярных выражений поддерживает потенциальные квантификаторы (хотя я подозреваю, что Google Analytics не поддерживает), то я думаю, это будет лучше для больших входных наборов:

^[^?]*+(?<!details\.cfm).*?selector=size.*$
Томалак
источник
Предполагается, selector=sizeчто всегда перед details.cfm, чего не происходит в последнем URL-адресе.
Коби
Чтобы прояснить это, это был не я. Я не понимаю, почему кто-то проголосовал против двух ответов здесь, они оба правильные.
Коби
@Kobi: Это должно было быть упущением, исправлено. Да, кстати, я не подозревал, что это было ваше голосование против.
Tomalak
0

Я искал способ избежать попадания --line-bufferedв хвост в подобной ситуации, поскольку решение OP и Kobi отлично работает для меня. В моем случае исключение строк с «ботом» или «пауком» при включении ' / '(для моего корневого документа).

Моя исходная команда:

tail -f mylogfile | grep --line-buffered -v 'bot\|spider' | grep ' / '

Теперь становится (с -Pпереключателем perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
руна
источник