2010-06-01 9 views
62

Ustanawiam kilka celów w Google Analytics i mogę skorzystać z niewielkiej pomocy z wyrażenia regularnego.Wyrażenie regularne dla ciągu znaków zawierającego jedno słowo, ale nie innego

Powiedzmy mam 4 adresy

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 ciąg selektora = 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ć w części selector = rozmiar.

Każda pomoc będzie bardzo ceniona!

Odpowiedz

86

ten powinien zrobić:

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

^.*selector=size.*$ powinno być wystarczająco jasne. Pierwszy bit, (?!.*details.cfm), jest negatywnym wyprzedzeniem: przed dopasowaniem napisu sprawdza, czy ciąg nie zawiera "details.cfm" (z dowolną liczbą znaków przed nim).

+2

FYI, sprawdź http://www.regexr.com/ na miły sposób na przetestowanie tych wyrażeń. –

+0

Świetnie, pomogło to. Dobre wyjaśnienie – user219628

+0

Zawsze zapominaj o negatywnym przeczuciu i jest tak użyteczny –

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

Jeśli silnik regex obsługiwane possessivus kwantyfikatorów (choć podejrzewam, Google Analytics nie), to myślę, że to będzie lepiej dla dużych linii ustawia:

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

Zakłada, że ​​'selector = size' jest zawsze przed' details.cfm', co nie ma miejsca w ostatnim adresie URL. – Kobi

+0

Aby to wyjaśnić, to nie byłem ja. Nie rozumiem, dlaczego ktoś głosowałby tutaj dwiema odpowiedziami, obie są poprawne. – Kobi

+0

@Kobi: To powinno być spojrzenie z wyprzedzeniem, poprawione. Aha, a przy okazji, nie podejrzewałem, że to był twój głos. – Tomalak

5

regex mogłyby być (składnia Perl) :

`/^[(^(?!.*details\.cfm).*selector=size.*)|(selector=size.*^(?!.*details\.cfm).*)]$/` 
-4

Prosty sposób, aby to zrobić, to podać 0 wystąpienia ciąg wykonując następujące

(string_to_exclude){0} 
+2

To nie działa. –

+0

to po prostu ocenia pusty ciąg; nie zapewnia, że ​​podciągi nie występują, ale że występuje pusty łańcuch, który zawsze ma –

0

Szukałem sposobu na uniknięcie - zbalansowanego liniowo na ogonie w podobnej sytuacji jak OP i rozwiązanie Kobi'ego działa doskonale dla mnie. W moim przypadku wykluczam linie z "bota" lub "pająkiem", a jednocześnie "/" (dla mojego głównego dokumentu).

Moje pierwotne polecenie:

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

Teraz staje się (z "-P" przełącznik perl):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'