il est donc impossible de faire une telle recherche en expression régulière ?
si je comprends bien les expressions régulières savent prendre en compte le "NE PAS" pour un caractère mais pas pour une chaine de caractères ?
il est donc impossible de faire une telle recherche en expression régulière ?
si je comprends bien les expressions régulières savent prendre en compte le "NE PAS" pour un caractère mais pas pour une chaine de caractères ?
Hum... je dois avouer qu'effectivement, je ne sais pas écrire une regex qui dit "trouver la chaine ne contient pas la chaine 'toto'".
Je sais écrire "trouver la chaine 'titi' qui n'est pas suivie par 'toto'", "trouver la chaine qui est composé de lettres sauf 't' et 'o'" ou éventuellement "trouver les chaines, sauf celles qui contiennent 'toto'".
Je ne pense pas avoir déjà eu besoin de ce cas. Il faut dire que si je ne trouve pas rapidement comment écrire une regex, je la reformule pour l'écrire autrement.
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.
Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]
et comment écris tu "trouver la chaine 'titi' qui n'est pas suivie par 'toto'" s'il te plait ?
Avec une assertion négative : titi(?!toto).
Le problème dans ton cas, c'est que la chaine 'titi' est plutôt du genre "titi suivi par n'importe quel caractère sans limitation de taille". Et du coup, il peut très trouver une chaine qui correspond à la regex, mais qui ne correspond pas à ce que tu cherches réellement.
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.
Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]
Pour trouver la chaîne qui ne contient pas "toto", il y a 4 manières de faire. Les autres sont des variantes:
1) On utilise les classes de caractères.
A/I: Ça fonctionne avec n'importe quel moteur de regex (aux différences de syntaxe prés), par contre passé un dizaine de caractères mieux vaut engager des moines copistes. Ce n'est pas très rapide, mais ce genre de méthode s'utilise plutôt avec les moteurs qui ne sont pas des moteurs à backtracking, qui donc ne dispose pas de lookahead, et dont les performances sont très bonnes.
2) Tous les caractères qui ne sont pas le début de "toto".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 (?:[^t]|t(?:[^o]|o(?:[^t]|t(?:[^o]|$)|$)|$))+ # version imbriquée (?:[^t]|t(?:[^o]|$)|to(?:[^t]|$)|tot(?:[^o]|$))+ # version non-imbriquée syntaxe POSIX étendue: (sans les groupes non-capturant) ([^t]|t([^o]|o([^t]|t([^o]|$)|$)|$))+ # version imbriquée ([^t]|t([^o]|$)|to([^t]|$)|tot([^o]|$))+ # version non-imbriquée syntaxe POSIX basique: (sans le quantifier +) \([^t]\|t\([^o]\|o\([^t]\|t\([^o]\|$\)\|$\)\|$\)\)\([^t]\|t\([^o]\|o\([^t]\|t\([^o]\|$\)\|$\)\|$\)\)* # version imbriquée \([^t]\|t\([^o]\|$\)|to\([^t]\|$\)|tot\([^o]\|$\)\)\([^t]\|t\([^o]\|$\)|to\([^t]\|$\)|tot\([^o]\|$\)\)* # version non-imbriquée
A/I: Facile à écrire et à comprendre, mais pas très efficace car pour chaque caractère on doit tester le lookahead (pour rien la plupart du temps). Un avantage de cette méthode est qu'elle permet plus facilement de composer une pattern dynamiquement si par exemple "toto" est stocké dans une variable. (Les autres méthodes exigent au minimum d'extraire le premier caractère "t" et le reste "oto" pour pouvoir faire la même chose).
(avec un modificateur s (singleline/dotall) ou en remplaçant le point par [\s\S] pour passer les sauts de ligne)
Code : Sélectionner tout - Visualiser dans une fenêtre à part (?:(?!toto).)+
3) Tous les caractères sauf "t" ou un "t" non suivi de "oto".
A/I: Même chose que précédemment en un peu mieux car le lookahead n'est testé que pour la lettre "t". Par contre si le texte contient beaucoup de "t", cette pattern devient plus lente car pour chaque "t" on doit tester les deux alternatives plus le lookahead.
3a) on attrape tous les caractères qui ne sont pas un "t" plage par plage:
Code : Sélectionner tout - Visualiser dans une fenêtre à part (?:[^t]|t(?!oto))+
A/I: plus efficace car le fait de devoir sortir du groupe, rencontrer le quantificateur et rentrer de nouveau dans le groupe représente un coût (allant de quasi-nul à énorme suivant les moteurs). Par contre cette pattern est inutilisable dans une expression si elle est suivie d'une sous-pattern pouvant échouer, car dans ce cas on aboutit à un catastrophic backtracking. Pour pallier à ce problème voir les variantes qui suivent.
3b) on utilise un groupe atomique ou un quantificateur possessif:
Code : Sélectionner tout - Visualiser dans une fenêtre à part (?:[^t]+|t(?!oto))+
Le groupe atomique interdit le backtracking pour les caractères matchés dans le groupe une fois la parenthèse fermante atteinte, il rend ce groupe de caractère indivisible (comme un atome). La position de bracktracking enregistrée par le moteur sera uniquement celle du début du groupe (donc soit il y est, soit il y est pas, mais on peut pas le saucissonner).
Le quantificateur possessif fait exactement la même chose, certains parlent parfois de sucre syntaxique pour le groupe atomique.
A/I: Tous les avantages de la pattern précédente sans les inconvénients. Le hic, c'est que ces deux outils ne sont pas supportés par tous les moteur de regex (c'est par exemple le cas de Javascript, et je ne l'ai pas vu non plus dans la doc de Dreamweaver qui doit probablement avoir le même moteur).
3c) on émule le groupe atomique:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 (?>(?:[^t]+|t(?!oto))+) # groupe atomique (?:[^t]+|t(?!oto))++ # quantificateur possessif
Pour les moteurs qui ne le supporte pas, il est possible d'émuler un groupe atomique en utilisant le fait qu'un lookahead est naturellement atomique. Il suffit alors de capturer l'expression dans le lookahead et de placer une référence au groupe capturé (backreference) à la suite.
A/I: Malgré le tour de passe-passe, les performances sont à la clef. On peut l'utiliser avec n'importe quel moteur dés lors qu'il dispose du lookahead, à l'exception du moteur d'Henry Spencer (Tcl, Postgresql) qui ne supporte pas les captures dans un lookahead. Le seul désavantage est la création d'un groupe de capture qui ne sert à rien.
4) on remplace l'alternative par des groupes optionnels:
Code : Sélectionner tout - Visualiser dans une fenêtre à part (?=((?:[^t]+|t(?!oto))+))\1
A/I: La plus rapide de toutes. Elle permet de s'affranchir des coûteuses alternatives répétés x fois et du coup réduit le nombre d'étapes d'une manière drastique. On peut l'agrémenter de quantificateurs possessifs ou changer le groupe non-capturant en groupe atomic suivant les besoins. Le seul problème est qu'elle peut matcher une chaîne vide, mais on peut facilement solutionner le problème par exemple avec une alternative (qui ne sera pour le coup testée qu'une seule fois).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 [^t]*(?:t(?!oto)[^t]*)* (?:[^t]|t(?!oto))[^t]*(?:t(?!oto)[^t]*)* # ou pour éviter la chaîne vide
Brachygobius xanthozonus
Ctenobrycon Gymnocorymbus
Woh !
Celira : Compétence : Regex, Niveau : 3
CosmoKnacki : Compétence : Regex, Niveau : 42
Modératrice PHP
Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.
Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager