Regex domain name (hostname)
Stack Overflow's top-voted answer (34 votes) on the reference question has a real flaw flagged in the comments: it validates a domain whose last label is entirely numeric (like "domaine.123"), which RFC 1912 specifically forbids to avoid confusion with an IP address. An answer citing the HTML Living Standard checks neither the overall length (255 characters max) nor that same point. Here's a pattern that fixes that specific flaw, compared against both of those attempts and a third one - tested by its author against a long list of real cases, yet still accepting consecutive dots.
/^(?!(?:.*\.)?[0-9]+\.?$)(?=.{1,255}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.?$/passes 23/23 cases
Comparison of existing patterns
| Source | pattern | Score on the corpus | ReDoS |
|---|---|---|---|
| Stack Overflow — réponse la plus votée (34 votes), valide un dernier segment entièrement numérique (bug signalé en commentaire, contraire à la RFC 1912) | ^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$ | 20 / 23 | safe |
| Stack Overflow — réponse testée sur une longue liste de cas réels par son auteur, accepte pourtant des points consécutifs et une longueur illimitée | ^[A-Za-z0-9][A-Za-z0-9-.]*\.\D{2,4}$ | 19 / 23 | safe |
| Stack Overflow — variante citant le HTML Living Standard, sans contrôle de longueur ni de point final ni de la règle RFC 1912 | ^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$ | 19 / 23 | undetermined |
Implementation
const re = new RegExp("^(?!(?:.*\\.)?[0-9]+\\.?$)(?=.{1,255}$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\\.?$", "");
re.test(input);Limits
- L'exclusion des noms se terminant par un segment entièrement numérique suit la RFC 1912, mais cette règle n'est pas toujours appliquée en pratique par les registres ou les résolveurs DNS : certains sous-domaines réellement utilisés (pas le domaine racine) sont entièrement numériques malgré la RFC.
- Ne vérifie que la forme du nom : ne consulte aucun DNS, ne garantit ni qu'un enregistrement existe pour ce nom, ni qu'un TLD donné (« .com », « .zzz »...) est réellement délégué par l'IANA.
- Ne traduit pas les noms de domaine internationalisés (IDN) écrits directement en caractères Unicode (« café.fr ») : seule leur forme Punycode déjà encodée (« xn--caf-dma.fr ») est reconnue, conformément à la limitation des classes [a-zA-Z0-9] à l'ASCII.
- Le contrôle de longueur globale (255 caractères) ne distingue pas la longueur de chaque étiquette individuelle (limitée à 63) de celle du nom complet : une étiquette de 64 caractères ou plus est déjà rejetée par ailleurs, mais un futur ajustement du motif devra conserver cette double contrainte séparément.