Mon problème est que je veux vérifier la chaîne de navigation avec une expression rationnelle pure.
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
-> devrait correspondre
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
ne doit pas correspondre
ma solution essayée est: /?((?<=Android)(?:[^])*?(?=Mobile))/i
mais elle correspond exactement mal.
Vous utilisez des assertions d'anticipation pour vérifier si une chaîne contient un mot ou non.
Si vous voulez vous assurer que la chaîne contient "Android" à un certain endroit, vous pouvez le faire comme ceci:
^(?=.*Android).*
Vous pouvez également les combiner, pour vous assurer qu'il contient "Android" à un endroit ET "Mobile" à un endroit:
^(?=.*Android)(?=.*Mobile).*
Si vous voulez vous assurer qu'un certain mot n'est pas dans la chaîne, utilisez l'anticipation négative:
^(?=.*Android)(?!.*Mobile).*
Cela nécessiterait que le mot "Android soit dans la chaîne et que le mot" Mobile "ne soit pas autorisé dans la chaîne. Le .*
part correspond alors à la chaîne/ligne complète lorsque les assertions au début sont vraies.
Voir ici sur Regexr
Je vais juste le casser
if ((m/Android/i) && (m/Safari/i) && !(m/Mobile Safari/i))
Cela dit, en fonction de la saveur regex, vous pouvez combiner cela
if ((m/Android/i) && (m/(?<!Mobile )Safari/i))
ou même
if (m/Android.*(?<!Mobile )Safari/i)
Pour info voir Lookahead/lookbehind
Mise à jour Testé correctement avec l'arôme regex Perl5 (sans doute l'arôme le plus populaire):
Perl -ne 'print "$. yes\n" if m/Android.*(?<!Mobile )Safari/i'
Spectacles:
1 yes
pour l'entrée donnée dans l'OP
Avec certaines implémentations d'expressions régulières, vous pouvez utiliser une assertion lookbehind négative. D'après les documents, un lookbehind négatif écrit comme (?<!...)
ne correspond que si la position actuelle dans la chaîne n'est pas précédée d'une correspondance pour ...
Voici un Python montrant comment utiliser le lookbehind négatif avec vos exemples de chaînes:
>>> 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