2010-06-01 12 views
62

Estoy estableciendo algunos objetivos en Google Analytics y podría usar un poco de ayuda de expresiones regulares.Expresión regular para una cadena que contiene una palabra pero no otra

Digamos que tengo 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 

Quiero crear una expresión que identificará cualquier URL que contiene el selector de cadena = tamaño pero no contiene details.cfm

Sé que para encontrar una cadena que NO contenga otra cadena, puedo usar esta expresión:

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

Pero no estoy seguro de cómo agregar selector = tamaño parte.

¡Cualquier ayuda sería muy apreciada!

Respuesta

86

Esto debe hacerlo:

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

^.*selector=size.*$ debe ser lo suficientemente claro. El primer bit, (?!.*details.cfm) es una mirada negativa hacia adelante: antes de hacer coincidir la cadena, verifica que la cadena no contenga "details.cfm" (con cualquier número de caracteres antes).

+2

su información, echa un vistazo a http://www.regexr.com/ para un buen forma de probar estas expresiones. –

+0

Brillante, esto ayudó. Buena explicación – user219628

+0

Olvídese siempre del lookahead negativo y es tan útil –

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

Si su motor de expresiones regulares apoyado cuantificadores posesivo (aunque sospecho que Google Analytics no), entonces creo que esto va a funcionar mejor para grandes conjuntos de entrada:

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

Esto supone que 'selector = size' siempre está antes de' details.cfm', que no es el caso en la última url. – Kobi

+0

Solo para aclarar esto, no fui yo. No veo por qué alguien podría votar dos respuestas aquí abajo, ambas son correctas. – Kobi

+0

@Kobi: Esto debería haber sido una anticipación, corregida. Ah, y por cierto, no sospeché que era tu voto negativo. – Tomalak

5

expresiones regulares podría ser (la sintaxis de Perl) :

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

Una manera sencilla de hacer esto es especificar 0 instancias de la cadena de la siguiente manera

(string_to_exclude){0} 
+2

Esto no funciona. –

+0

esto simplemente evalúa la cadena vacía; no garantiza que no se produzca la subcadena, pero que la cadena vacía sí ocurre, lo que siempre ocurre –

0

Estaba buscando una manera de evitar --línea amortiguada en una cola en una situación similar a la OP y la solución de Kobi funciona muy bien para mí. En mi caso, excluyendo líneas con "bot" o "spider" mientras incluyo '/' (para mi documento raíz).

Mi mandamiento original:

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

Ahora se hace (con "-P" interruptor de Perl):

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