Espressione regolare per una stringa contenente una parola ma non un'altra


103

Sto impostando alcuni obiettivi in ​​Google Analytics e potrei utilizzare una piccola guida regex.

Diciamo che ho 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

Voglio creare un'espressione che identificherà qualsiasi URL che contiene la stringa selector = size ma NON contiene details.cfm

So che per trovare una stringa che NON contiene un'altra stringa posso usare questa espressione:

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

Ma non sono sicuro di come aggiungere nel selettore = porzione di dimensioni .

Qualsiasi aiuto sarebbe molto apprezzato!

Risposte:


144

Questo dovrebbe farlo:

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

^.*selector=size.*$dovrebbe essere abbastanza chiaro. Il primo bit, (?!.*details.cfm)è un look-ahead negativo: prima di abbinare la stringa controlla che la stringa non contenga "details.cfm" (con qualsiasi numero di caratteri prima di essa).


8
Cordiali saluti, controlla regexr.com per un bel modo per testare queste espressioni.
Joshua Pinter

Dimentica sempre il lookahead negativo ed è così utile
Alexei Blue

"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0non è corretto. (Nota che la stringa contiene "...selector=sized...".) Inoltre, perché .*$alla fine?
Cary Swoveland

4

regex potrebbe essere (sintassi perl):

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

Questa è un'espressione regolare corrotta, le parentesi quadre trasformano tutte le sequenze di pattern in una combinazione di singoli caratteri.
Wiktor Stribiżew

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

Se il tuo motore regex supporta quantificatori positivi (anche se sospetto che Google Analytics non lo faccia), immagino che funzionerà meglio per set di input di grandi dimensioni:

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

Ciò presuppone che selector=sizesia sempre prima details.cfm, il che non è il caso dell'ultimo URL.
Kobi

Solo per chiarire, non sono stato io. Non riesco a capire perché qualcuno voterebbe per difetto due risposte qui, sono entrambe corrette.
Kobi

@ Kobi: questo avrebbe dovuto essere uno sguardo al futuro, corretto. Oh, a proposito, non sospettavo che fosse il tuo voto negativo.
Tomalak

0

Stavo cercando un modo per evitare --line-buffereduna coda in una situazione simile poiché l'OP e la soluzione di Kobi funziona alla grande per me. Nel mio caso escludendo righe con "bot" o "spider" includendo ' / '(per il mio documento di root).

Il mio comando originale:

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

Ora diventa (con -Pperl switch):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.