Rexact
Cheatsheet

Regex web URL

A 15-upvote comment on the reference question (779,000 views) cites a regex from an old Microsoft documentation page as "the right one". Our ReDoS analysis flags it as vulnerable, exponential complexity, with a concrete attack string. Here's Diego Perini's "web URL" pattern (1600+ GitHub stars), compared against 3 really-copied attempts.

/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9¡-￿][a-z0-9¡-￿_-]{0,62})?[a-z0-9¡-￿]\.)+(?:[a-z¡-￿]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i
passes 20/20 cases

Comparison of existing patterns

SourcepatternScore on the corpusReDoS
Stack Overflow — commentaire citant une regex Microsoft (page MSDN retirée), 15 votes^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$11 / 20vulnerable (ftp://psssssssssssssssssssssssssssssssssssssssssssssssssssss…)
Stack Overflow — réponse de Divya-Systematix (classe de caractères mal formée)^(http|https):\/\/+[\www\d]+\.[\w]+(\/[\w\d]+)?$13 / 20safe
Stack Overflow — le motif « en une ligne » très largement copié^(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6}|:[0-9]{3,4})\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)$13 / 20undetermined

Implementation

const re = new RegExp("^(?:(?:(?:https?|ftp):)?\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z0-9¡-￿][a-z0-9¡-￿_-]{0,62})?[a-z0-9¡-￿]\\.)+(?:[a-z¡-￿]{2,}\\.?))(?::\\d{2,5})?(?:[/?#]\\S*)?$", "i");
re.test(input);

Limits

  • Le port n'est vérifié que par son nombre de chiffres (2 à 5), pas par sa plage réelle : « https://example.com:99999 » passe alors que ce port n'existe pas (les ports réels vont de 0 à 65535).
  • Exclut volontairement les noms à un seul label comme « localhost » — un choix assumé pour une URL web publique, pas adapté à un contexte de développement local.
  • Exclut les adresses IP privées ou réservées (10.x, 172.16-31.x, 192.168.x…) : une URL techniquement valide sur un réseau interne sera rejetée, un comportement volontaire pour éviter qu'un formulaire public pointe vers un réseau local.
  • Accepte la forme protocole-relatif (« //example.com ») et l'authentification intégrée à l'URL (« user:pass@… »), deux formes valides mais dont la seconde est dépréciée par les navigateurs modernes pour des raisons de sécurité.