Regex pour les URL : ce qu'il faut reconnaître et ce qu'il faut laisser à un analyseur
Trouver des liens dans un texte et valider une URL sont deux tâches différentes. Voici un motif pour chacune, les pièges qui laissent passer de mauvaises URL (ponctuation finale, points non échappés, ancres manquantes), et quand confier le travail à new URL() ou à urllib.

· 8 min de lecture · Mis à jour le
/^https?://\S+$/
à attraper
- https://a.io
- http://x.com/p
- https://b.dev?q=1
à épargner
- ftp://x.com
- www.x.com
- http:/x.com
« Regex d'URL » désigne en général l'une de ces deux choses :
- Trouver des URL dans un bloc de texte, comme une messagerie qui transforme les liens en éléments cliquables.
- Valider une saisie unique, comme un champ « Site web » dans un formulaire de profil.
Il leur faut des motifs différents, et la seconde relève surtout d'un analyseur d'URL. Cet article couvre les deux, ainsi que les pièges propres à chacune. Tous les exemples sont interactifs : modifiez les motifs et observez ce qui change.
/^ (https?) :// ([^/:?#\s]+) (:\d+)? (/[^?#\s]*)? (\?[^#\s]*)? (#\S*)?$/iUne URL http ou https avec un hôte, puis un port, un chemin, une requête et un fragment facultatifs, sans espaces.
Accepte
- https://example.com
- http://localhost:3000/api?x=1
- https://example.com/blog#top
Rejette
- ftp://example.com
- www.example.com
- https://exa mple.com
01Trouver des URL dans du texte
La version rapide : un schéma suivi de tout ce qui n'est pas un espace :
/https?://\S+/Doit correspondre3/3
- Docs: https://regexhunter.com/guide.
- (see https://example.com/a)
- <https://example.com>
Ne doit pas2/2
- see www.example.com
- ftp://files.example.com
\S+ prend tout jusqu'à l'espace suivant, et dans un vrai texte, une URL est souvent suivie de ponctuation. Faites-en un lien, et le lecteur tombe sur une 404.
02Écarter la ponctuation finale
La solution consiste à dire ce que peut être le dernier caractère. Le corps peut contenir n'importe quoi sauf des espaces, des chevrons et des guillemets. Le dernier caractère ne peut pas non plus être une ponctuation courante :
/https?://[^\s<>"]*[^\s<>".,;:!?)]/- Docs: https://regexhunter.com/guide.
- (see https://example.com/a)
- <https://example.com>
- https://example.com/search?q=regex&page=2
Cela marche parce que le [^\s<>"]* gourmand court jusqu'au bout de l'URL, puis recule d'un caractère à la fois jusqu'à ce que la classe finale convienne. (Notre article sur les quantificateurs gourmands et paresseux détaille ce recul.)
Il n'existe pas de règle parfaite ici. Des liens Wikipédia comme https://en.wikipedia.org/wiki/Regex_(disambiguation) se terminent vraiment par ), et ce motif la retire. Les bibliothèques de détection de liens règlent ça en vérifiant si les parenthèses sont équilibrées, ce qui est plus de logique qu'une seule regex ne devrait en porter.
Remarquez que www.example.com n'est pas trouvé, faute de schéma. Si vous voulez aussi les liens www. sans schéma, commencez plutôt le motif par (https?://|www\.).
03Valider une URL : les parties
Une URL web compte jusqu'à six parties. Les voici dans https://regexhunter.com:443/blog/regex-urls?ref=home#top :
| Partie | Exemple | Obligatoire ? |
|---|---|---|
| schéma | https |
oui |
| hôte | regexhunter.com |
oui |
| port | :443 |
non |
| chemin | /blog/regex-urls |
non |
| requête | ?ref=home |
non |
| fragment | #top |
non |
Un motif qui vérifie la forme de chaque partie ressemble à ceci :
/^(https?)://([^/:?#\s]+)(:\d+)?(/[^?#\s]*)?(\?[^#\s]*)?(#\S*)?$/iDoit correspondre4/4
- https://example.com
- HTTPS://EXAMPLE.COM
- http://localhost:3000/api?x=1
- https://regexhunter.com/blog/regex-urls#top
Ne doit pas5/5
- ftp://example.com
- https://
- https://exa mple.com
- https://example.com:port
- example.com
Lisez-le partie par partie :
^(https?)://le schéma, http ou https, et le://([^/:?#\s]+)l'hôte : tout jusqu'au prochain/,:,?ou#(:\d+)?un port facultatif, uniquement des chiffres(/[^?#\s]*)?un chemin facultatif, qui commence par/(\?[^#\s]*)?une requête facultative, qui commence par?(#\S*)?$un fragment facultatif, puis la fin
C'est une bonne vérification de forme. Mais elle ne dit rien de la cohérence de l'hôte. https://999.999.999.999 passe, et https://- aussi. Vous pourriez continuer à ajouter des règles pour les noms d'hôte, les adresses IP, les crochets IPv6, les identifiants et mots de passe, et les noms de domaine internationalisés. Certains l'ont fait, et le résultat se compte en centaines de caractères.
04Laissez un analyseur faire l'analyse
Tous les langages courants fournissent un analyseur d'URL qui connaît déjà ces règles. En JavaScript (navigateurs et Node), le constructeur URL lève une exception sur tout ce qu'il ne sait pas analyser :
function isHttpUrl(s) {
try {
const u = new URL(s);
return u.protocol === 'http:' || u.protocol === 'https:';
} catch {
return false;
}
}
new URL("https://exa mple.com"), new URL("https://999.999.999.999") et new URL("example.com") lèvent tous une exception. La vérification du protocole compte : new URL("javascript:alert(1)") s'analyse sans problème, et vous ne voulez pas de ça dans un lien.
Vous obtenez aussi les morceaux gratuitement : u.hostname, u.port, u.pathname, u.search, u.hash, et u.searchParams.get("x") pour une valeur de la requête. Et l'URL revient normalisée : HTTPS://Example.COM:443/a/../b devient https://example.com/b.
En Python, urllib.parse.urlsplit découpe une URL en ces mêmes parties :
from urllib.parse import urlsplit
u = urlsplit("http://localhost:3000/api?x=1#top")
(u.scheme, u.hostname, u.port, u.path, u.query, u.fragment)
# ('http', 'localhost', 3000, '/api', 'x=1', 'top')
Mais urlsplit découpe, il ne valide pas. Il lève rarement une erreur. urlsplit("example.com") renvoie un schéma et un hôte vides, avec example.com comme chemin, et urlsplit("https://exa mple.com") annonce sans sourciller exa mple.com comme hôte. Vérifiez donc u.scheme in ("http", "https") et que u.netloc n'est pas vide, puis ajoutez vos propres règles sur l'hôte si besoin.
05Piège : le point non échappé
Dans un motif, . veut dire « n'importe quel caractère ». Oubliez la barre oblique inverse dans un nom de domaine, et vous autorisez des domaines sosies :
/^https://www.example.com/- https://www.example.com
- https://wwwxexample.com
Écrivez www\.example\.com. Chaque point littéral d'un motif a besoin d'une barre oblique inverse.
06Piège : la fin manquante
Celui-ci compte pour les redirections et les listes d'autorisation, du genre « ne renvoyer les gens que vers des URL de notre propre site » :
/^https://example\.com/- https://example.com/login
- https://example.com.evil.io
L'hôte doit s'arrêter juste après .com. Exigez l'un des caractères qui peuvent le terminer, ou la fin de la chaîne :
/^https://example\.com([/?#:]|$)/Doit correspondre3/3
- https://example.com
- https://example.com/login
- https://example.com?ref=mail
Ne doit pas3/3
- https://example.com.evil.io
- https://example.company.io
- https://evil.io/?next=https://example.com
Encore mieux pour les contrôles de sécurité : analysez avec new URL() ou urlsplit, puis comparez le nom d'hôte avec === ou ==. Une comparaison exacte de chaînes n'a aucun cas limite à oublier.
07À vous de jouer
Chaque monstre est une adresse web. Les innocents ont le mauvais schéma, un :// cassé, une faute de frappe, ou pas de schéma du tout :
Attrapez les adresses http et https, épargnez le reste.
Cibles · 0/4 attrapées
- https://regexhunter.comcible
- http://localhost:3000cible
- https://a.io/x?y=1cible
- http://example.org/cible
Innocents · erreurs : 0
- ftp://example.orginnocent
- https:/broken.cominnocent
- example.cominnocent
- mailto:ana@site.cominnocent
- htps://typo.ioinnocent
Tapez une regex — le plateau se met à jour en direct.
08Récapitulatif
- Pour trouver des URL dans du texte :
https?://[^\s<>"]*[^\s<>".,;:!?)], pour laisser la ponctuation finale dehors. - Pour valider une URL : utilisez
new URL()en JavaScript et vérifiez le protocole, ouurlspliten Python et vérifiez le schéma et l'hôte. - Échappez chaque point littéral :
example\.com. - Dans les listes d'autorisation, ancrez le début et la fin de l'hôte, ou mieux, comparez les noms d'hôte analysés.
- Ajoutez le marqueur
isi des majuscules peuvent apparaître.HTTPS://EXAMPLE.COMest une URL valide.
09Continuez à vous entraîner
- Le parcours Validateurs du monde réel de l'Académie comprend des slugs d'URL, des e-mails, des adresses IP et bien plus.
- La section du guide sur l'échappement couvre les règles de la barre oblique inverse au cœur du piège du point.
- Essayez la chasse du jour, ou parcourez les plateaux passés dans les archives.