regex - solo - ¿Hay una expresión regular para coincidir con una cadena que contiene A pero no contiene B
javascript regex test (3)
Mi problema es que quiero verificar el navegador con pura expresión regular.
Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13
-> debe coincidir
Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
no debe coincidir
mi solución probada es: /?((?<=Android)(?:[^])*?(?=Mobile))/i
pero coincide exactamente mal.
Con algunas implementaciones de expresiones regulares, puede utilizar una aserción de mirada negativa detrás. Según los documentos, un aspecto negativo escrito detrás de (?<!...)
solo coincide si la posición actual en la cadena no está precedida por una coincidencia para ...
Aquí hay un script interactivo de Python que muestra cómo usar la apariencia negativa detrás de las cadenas de muestra:
>>> s = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
>>> bool(re.search(r''Android.*(?<! Mobile) Safari'', s))
True
>>> t = "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
>>> bool(re.search(r''Android.*(?<! Mobile) Safari'', t))
False
Solo lo rompería
if ((m/Android/i) && (m/Safari/i) && !(m/Mobile Safari/i))
Dicho esto, dependiendo del regex flaviour, podrías combinar eso
if ((m/Android/i) && (m/(?<!Mobile )Safari/i))
o incluso
if (m/Android.*(?<!Mobile )Safari/i)
Para tu información, mira hacia Lookahead/lookbehind
Actualización Probado estos bien con el sabor de regex Perl5 (posiblemente el sabor más popular):
perl -ne ''print "$. yes/n" if m/Android.*(?<!Mobile )Safari/i''
Muestra:
1 yes
para la entrada dada en el OP
Utiliza las aseveraciones anticipadas para verificar si una cadena contiene una palabra o no.
Si desea asegurarse de que la cadena contenga "Android" en algún lugar, puede hacerlo de la siguiente manera:
^(?=.*Android).*
También puedes combinarlos para asegurarte de que contiene "Android" en algún lugar Y "Mobile" en algún lugar:
^(?=.*Android)(?=.*Mobile).*
Si desea asegurarse de que una determinada palabra NO esté en la cadena, use la vista negativa hacia adelante:
^(?=.*Android)(?!.*Mobile).*
Esto requeriría que la palabra "Android esté en la cadena y la palabra" Móvil "no está permitida en la cadena. La parte .*
Coincide con la cadena / fila completa cuando las afirmaciones al principio son verdaderas.