Wyrażenie regularne dla łańcucha zawierającego jedno słowo, ale nie inne

103

Ustawiam cele w Google Analytics i przydałaby mi się pomoc dotycząca wyrażeń regularnych.

Powiedzmy, że mam 4 adresy 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

Chcę utworzyć wyrażenie, które będzie identyfikować dowolny adres URL, który zawiera selektor ciągu = rozmiar, ale NIE zawiera details.cfm

Wiem, że aby znaleźć ciąg, który NIE zawiera innego ciągu, mogę użyć tego wyrażenia:

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

Ale nie jestem pewien, jak dodać selektor = rozmiar .

Każda pomoc byłaby bardzo mile widziana!

Chris Stahl
źródło

Odpowiedzi:

144

To powinno wystarczyć:

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

^.*selector=size.*$powinien być wystarczająco jasny. Pierwszy bit (?!.*details.cfm)jest ujemnym wyprzedzeniem: przed dopasowaniem łańcucha sprawdza, czy ciąg nie zawiera „details.cfm” (z dowolną liczbą znaków przed nim).

Kobi
źródło
8
FYI, sprawdź regexr.com, aby znaleźć dobry sposób na przetestowanie tych wyrażeń.
Joshua Pinter
Zawsze zapominaj o negatywnym spojrzeniu w przód i jest to bardzo przydatne
Alexei Blue
"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0jest nieprawidłowe. (Zwróć uwagę na ciąg zawiera "...selector=sized...".) Poza tym, dlaczego .*$na końcu?
Cary Swoveland,
4

wyrażenie regularne mogłoby wyglądać (składnia perla):

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/`
djipko
źródło
To jest uszkodzone wyrażenie regularne, nawiasy kwadratowe zamieniają wszystkie sekwencje wzorów w kombinacje pojedynczych znaków.
Wiktor Stribiżew
2
^(?=.*selector=size)(?:(?!details\.cfm).)+$

Jeśli Twój silnik wyrażeń regularnych obsługuje dodatnie kwantyfikatory (chociaż podejrzewam, że Google Analytics nie obsługuje), to myślę, że będzie to działać lepiej w przypadku dużych zbiorów danych wejściowych:

^[^?]*+(?<!details\.cfm).*?selector=size.*$
Tomalak
źródło
Zakłada selector=sizesię, że zawsze jest przed details.cfm, co nie ma miejsca w ostatnim adresie URL.
Kobi
Żeby to wyjaśnić, to nie byłem ja. Nie rozumiem, dlaczego ktoś miałby tutaj przegłosować dwie odpowiedzi, obie są poprawne.
Kobi
@Kobi: To powinno być wybiegające w przyszłość, poprawione. Aha, tak przy okazji, nie podejrzewałem, że to twój głos przeciw.
Tomalak
0

Szukałem sposobu na uniknięcie sytuacji --line-bufferedna ogonie w podobnej sytuacji jak OP i rozwiązanie Kobi działa dla mnie świetnie. W moim przypadku wykluczanie wierszy z „botem” lub „pająkiem” podczas włączania' / ' (dla mojego dokumentu głównego).

Moje oryginalne polecenie:

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

Teraz staje się (z -Pprzełącznikiem Perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
roon
źródło