Регулярний вираз для рядка, що містить одне слово, але не інше


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, але НЕ містить деталей.cfm

Я знаю, що для пошуку рядка, який НЕ містить іншої рядки, я можу використовувати цей вираз:

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

Але я не впевнений, як додати в селектор = частина розміру .

Будь-яка допомога буде дуже вдячна!

Відповіді:


144

Це слід зробити:

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

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


8
FYI, ознайомтеся з regexr.com, щоб приємно перевірити ці вирази.
Джошуа Пінтер

Завжди забувайте про негативну лукахеду, і це так корисно
Олексій Блю

"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 Stribiżew

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

Якщо ваш механізм регулярних операцій підтримує позитивні кількісні показники (хоча, мабуть, Google Analytics не робить), я думаю, що це буде краще для великих наборів введення:

^[^?]*+(?<!details\.cfm).*?selector=size.*$

Це передбачає, що selector=sizeце завжди раніше details.cfm, що не стосується останньої URL-адреси.
Кобі

Просто для того, щоб прояснити це, це був не я. Я не бачу, чому хтось би тут проголосував дві відповіді, вони обидва правильні.
Кобі

@Kobi: Це повинно було бути випереджено, виправлено. О, і до речі, я не підозрював, що це ваш голосування.
Томалак

0

Я шукав спосіб уникнути --line-bufferedхвоста в подібній ситуації, оскільки рішення ОП та Кобі спрацює для мене чудово. У моєму випадку виключаючи рядки з "ботом" або "павуком", включаючи ' / '(для мого кореневого документа).

Моя оригінальна команда:

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

Тепер стає (за допомогою -Pперемикача perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.