Ma regex marche dans le testeur mais pas dans mon code — voici pourquoi
Le motif n'est presque jamais en cause. Ce sont l'échappement, les drapeaux ou un moteur de regex différent — et chacun a un symptôme caractéristique qui vous dit auquel des trois vous avez affaire.
Vous construisez un motif dans un testeur en ligne, il correspond parfaitement, vous le collez dans votre code et il ne correspond à rien. La regex n'a pas changé, donc quelque chose autour a changé. En pratique c'est l'une de trois choses : le motif a été abîmé par l'échappement dans une chaîne, les drapeaux n'ont pas voyagé avec lui, ou votre langage utilise un moteur de regex différent de celui du testeur.
Échappement : le motif dans votre code n'est pas celui que vous avez écrit
C'est de loin la cause la plus fréquente, et elle survient dès que la regex vit dans une chaîne plutôt que dans un littéral d'expression régulière. Dans une chaîne, l'antislash est lui-même un caractère d'échappement : il est consommé avant même que le moteur de regex ne le voie. Votre \d devient un simple d, et \. devient un point littéral qui correspond désormais à n'importe quel caractère. Le motif que reçoit le moteur est réellement différent de celui que vous avez tapé. La solution varie selon le langage : en JavaScript préférez la forme littérale /\d+/ à new RegExp("\\d+") ; en Python utilisez une chaîne brute, r"\d+" ; en Java et C# vous devez doubler chaque antislash, ou utiliser les chaînes verbatim @"..." de C#.
Les drapeaux se configurent à part et ne se copient pas
Les testeurs en ligne placent les drapeaux dans leur propre petite case à côté du motif : quand vous sélectionnez et copiez, vous emportez le motif et laissez les drapeaux derrière. Trois comptent particulièrement. Le drapeau m fait passer ^ et $ de « début et fin de toute la chaîne » à « début et fin de chaque ligne » — sans lui, un motif qui fonctionnait sur un bloc de texte de test multiligne échouera. Le drapeau s permet à . de correspondre aux sauts de ligne, ce qu'il ne fait pas par défaut. Et le drapeau i d'insensibilité à la casse est celui dont on oublie le plus souvent qu'il était activé.
Le drapeau g a son propre piège
En JavaScript, une regex avec le drapeau g est à état : elle conserve une propriété lastIndex qui avance après chaque correspondance. Si vous réutilisez ce même objet regex avec .test() dans une boucle, vous obtenez des résultats alternés true et false pour une entrée identique, ce qui ressemble à du non-déterminisme et rend le débogage insupportable. Recréez la regex à chaque fois, retirez le drapeau g quand vous n'avez besoin que d'un booléen, ou remettez lastIndex à zéro entre les appels.
Tous les moteurs ne parlent pas le même dialecte
La plupart des testeurs en ligne utilisent PCRE par défaut, la saveur compatible Perl. Votre code ne l'utilise peut-être pas. Les assertions arrière, les groupes nommés et les quantificateurs possessifs varient en prise en charge. L'exemple le plus frappant est RE2, utilisé par Go et plusieurs bases de données, qui omet délibérément les rétroréférences et l'anticipation pour garder un temps de correspondance linéaire — un motif qui en dépend ne se contente pas d'échouer, il refuse de compiler. Si votre testeur propose un sélecteur de moteur, réglez-le sur votre langage réel avant de construire le motif, pas après qu'il casse.
Correspondance partielle contre correspondance complète
Les testeurs vous montrent presque toujours chaque correspondance partielle surlignée dans le texte, mais beaucoup d'API de langage posent une question différente. Le matches() de Java exige que le motif consomme toute l'entrée, tandis que find() cherche une correspondance n'importe où — un motif qui s'illumine joyeusement dans un testeur renvoie donc false depuis matches(). Python a la même division en trois entre re.match, re.search et re.fullmatch. Si votre motif semble correct mais renvoie false, vérifiez laquelle de ces fonctions vous avez appelée avant de toucher à la regex.
L'étape de débogage qui le trouve le plus vite
Affichez le motif compilé à l'exécution — pas la ligne source, mais la valeur réelle reçue par le moteur. En JavaScript c'est String(maRegex), en Python print(motif.pattern). Si ce que vous voyez diffère de ce que vous avez écrit, c'est un problème d'échappement et vous l'avez trouvé en une étape. Si cela correspond exactement, le problème vient des drapeaux ou du dialecte, et vous avez éliminé deux tiers des possibilités sans deviner.
Notre testeur de regex affiche le motif, les drapeaux et les correspondances côte à côte, et surligne les groupes au fil de la frappe, pour que vous confirmiez la combinaison exacte de motif et de drapeaux avant qu'elle parte dans votre code. Il s'exécute dans votre navigateur, vous pouvez donc tester sur de vraies données sans risque.