Regex numéro de téléphone américain
La réponse la plus votée (411 votes) sur la question de référence a un vrai défaut signalé en commentaire : ses parenthèses autour de l'indicatif régional sont chacune indépendamment optionnelles, ce qui laisse passer « (212 456 7890 » (parenthèse ouvrante sans fermante). Une troisième tentative, très permissive, est carrément vulnérable au ReDoS d'après notre analyse (complexité polynomiale, vérifiée sur une chaîne de simples espaces) : ses deux premiers quantificateurs peuvent tous deux consommer le même caractère espace. Un commentaire sur une autre question du même sujet signale une deuxième règle réelle ignorée par la tentative de l'auteur lui-même : un indicatif régional américain ne peut jamais commencer par 0 ou 1 (plan de numérotation NANP). Voici un motif sûr qui corrige ces trois points, comparé aux 3 tentatives réelles.
/^(?:\+?1[-.\s]?)?(?:\([2-9]\d{2}\)|[2-9]\d{2})[-.\s]?[2-9]\d{2}[-.\s]?\d{4}(?:\s*x\d+)?$/iComparatif des patterns existants
| Source | pattern | Score sur le corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — réponse la plus votée (411 votes), parenthèses non appariées (bug signalé en commentaire : accepte « (212 456 7890 ») | ^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$ | 13 / 20 | sûr |
| Stack Overflow — tentative de l'auteur de la question, non ancrée en fin de chaîne, autorise un indicatif commençant par 1 (bug signalé en commentaire, contraire au plan NANP) | ^[1-9]\d{2}-\d{3}-\d{4} | 11 / 20 | sûr |
| Stack Overflow — réponse à 247 votes, très permissive, accepte des séparateurs répétés à volonté et aucune contrainte NANP | ^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$ | 15 / 20 | vulnérable ( …) |
Implémentation
const re = new RegExp("^(?:\\+?1[-.\\s]?)?(?:\\([2-9]\\d{2}\\)|[2-9]\\d{2})[-.\\s]?[2-9]\\d{2}[-.\\s]?\\d{4}(?:\\s*x\\d+)?$", "i");
re.test(input);Limites
- Valide uniquement la FORME : ne vérifie ni qu'un indicatif régional donné est réellement attribué par le plan NANP, ni que le numéro complet correspond à une ligne active.
- N'accepte qu'un préfixe pays « 1 » (Amérique du Nord) : les autres formats internationaux (« +44 », « +33 »...) ne sont volontairement pas couverts, conformément à l'intitulé de la question source qui cible spécifiquement le format américain.
- N'impose pas la cohérence des séparateurs entre les groupes de chiffres : « 212-456.7890 » (tiret puis point) est accepté aussi bien que « 212-456-7890 », ce qui est correct pour la validation mais ne normalise pas l'affichage.
- Ne reconnaît que l'extension au format « x1234 » : la forme alternative « ext. 1234 », également répandue, n'est pas couverte par ce motif.