Expresión regular para una cadena que contiene una palabra pero no otra


103

Estoy configurando algunos objetivos en Google Analytics y me vendría bien un poco de ayuda con las expresiones regulares.

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 identifique cualquier URL que contenga el selector de cadena = tamaño pero NO contenga detalles.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 la porción selector = tamaño .

¡Cualquier ayuda será muy apreciada!

Respuestas:


144

Esto debería hacerlo:

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

^.*selector=size.*$debe ser lo suficientemente claro. El primer bit (?!.*details.cfm)es un avance negativo: antes de hacer coincidir la cadena, comprueba que la cadena no contiene "detalles.cfm" (con cualquier número de caracteres antes).


8
Para su información, visite regexr.com para ver una buena manera de probar estas expresiones.
— Joshua Pinter

Olvídese siempre de la anticipación negativa y es muy útil
— Alexei Blue

"http://www.anydotcom.com/test/search.cfm?metric=blah&selector=sized&value=1" =~ /^(?!.*details\.cfm).*selector=size.*$/ #=> 0Es incorrecto. (Tenga en cuenta que la cadena contiene "...selector=sized..."). Además, ¿ .*$por qué al final?
— Cary Swoveland

4

regex podría ser (sintaxis de perl):

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

Esta es una expresión regular corrupta, los corchetes convierten todas las secuencias de patrones en una combinación de caracteres individuales.
— Wiktor Stribiżew

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

Si su motor de expresiones regulares admitía cuantificadores posesivos (aunque sospecho que Google Analytics no lo hace), supongo que esto funcionará mejor para grandes conjuntos de entrada:

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

Esto supone selector=sizeque siempre es antes details.cfm, que no es el caso en la última URL.
— Kobi

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

@Kobi: Esto debería haber sido una anticipación, corregido. Ah, y por cierto, no sospeché que fuera su voto en contra.
— Tomalak

0

Estaba buscando una manera de evitar la --line-bufferedcola en una situación similar, ya que el OP y la solución de Kobi funcionan muy bien para mí. En mi caso, excluir líneas con "bot" o "araña" mientras se incluyen ' / '(para mi documento raíz).

Mi comando original:

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

Ahora se convierte (con -Pperl switch):

tail -f mylogfile | grep -P '^(?!.*(bot|spider)).*\s\/\s.*$'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.