De zéro à expert Regex
Extraire et analyser des chaînes de type URL avec une seule expression régulière
Table des matières
- 🚀 Introduction
- 🔍 Extraction des URLs depuis du texte brut
- 🛳️ La regex de plus de 120 octets
- 🧩 Décomposition étape par étape
- 🛠️ Exemple d’analyse
- ☑️ Prochaines étapes
- 📝 Résumé
- 📚 Pour aller plus loin
TL;DR : Passez directement à la regex de plus de 120 octets.
🚀 Introduction
L’extraction d’URLs depuis du texte brut peut parfois ressembler à une partie de whack-a-mole. La ponctuation, les parenthèses englobantes et les formats ambigus s’associent pour saboter vos efforts. Que vous développiez un web scraper, un analyseur de données ou une application de chat, l’extraction fiable des URLs est indispensable.
Dans cet article, nous abordons le problème de front avec une approche flexible en deux étapes. Notre objectif est de capturer toutes les chaînes potentielles de type URL en premier, puis de traiter la validation dans une étape ultérieure.
💡 Note : Ce pattern ne sert pas à valider des URLs ! Il est délibérément permissif concernant la ponctuation et les erreurs de saisie.
🔍 Objectif : Extraire des URLs depuis du texte
Lors de l’extraction d’URLs depuis du texte brut, une approche en deux étapes fait ses preuves :
- Capturer tout ce qui ressemble à une URL : Lancer un large filet pour saisir toutes les chaînes qui pourraient être des URLs. C’est là que notre “regex de plus de 120 octets” montre toute son utilité.
- Valider : Une fois ces candidats capturés, utilisez des vérifications secondaires (par ex. résolution DNS, comparaison avec des domaines connus) pour écarter les entrées invalides.
Visualiser le défi
Les termes extract et parse sont souvent employés de manière interchangeable, mais ils désignent des processus distincts. L’extraction d’URL consiste à identifier et à capturer des chaînes susceptibles d’être des URL au sein d’un texte plus large. Le parsing, en revanche, consiste à décomposer ces URL en leurs composants élémentaires.
Lorsque j’évoque le parsing ou les « parties d’une URL », je fais référence aux composants suivants :
Cliquez pour afficher une capture d’écran de la correspondance de sous-chaîne sur RegEx101.
Avant d’entrer trop profondément dans la regex, utilisons un outil visuel pour évaluer la capacité de mon pattern à capturer un grand nombre de correspondances :

La regex de plus de 120 octets
Voici une regex concise conçue pour extraire et analyser les URL en une seule passe. Elle prend en charge divers protocoles, domaines, chemins, ainsi que les sections optionnelles de requête et de fragment.
Ne vous inquiétez pas — nous allons l’analyser étape par étape !
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;// Compatibility: ES5+
// Same pattern, split on newlines for readability:([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)Partagez les regex les plus délirantes que vous ayez rencontrées (ou rédigées) dans les commentaires ci-dessous ! 🚀
🧩 Décomposition étape par étape
Décortiquons la regex en ses composants pour comprendre son fonctionnement :
1. Protocole (Groupe 1) : ([-.a-z0-9]+:/{1,3})
- Objectif : Capture la partie protocole de l’URL (ex.
http://,ftp://,custom-scheme://). Explication :
[-.a-z0-9]+: Correspond à une ou plusieurs lettres minuscules, chiffres, tirets ou points (courant dans les schémas de protocole).:/{1,3}: Correspond à un deux-points suivi de une à trois barres obliques (:/,://ou:///).
2. Domaine (Groupe 2) : ([^-/.[](|)s?][^`/s]?]+)
- Objectif : Capture la partie domaine ou hôte de l’URL.
Explication :
[^-/.[](|)\s?]: Correspond à tout caractère sauf les caractères spéciaux et espaces indiqués.[^`/\s]?]+: Correspond à un ou plusieurs caractères sauf les backticks, barres obliques, espaces ou crochets fermants.
3. Chemin (Groupe 3) : ([-_a-z0-9!@$%^&*()=+;/~\.]*)
- Objectif : Correspond au composant chemin de l’URL.
Explication :
[-_a-z0-9!@$%^&()=+;/~.]: Correspond à zéro ou plusieurs caractères sécurisés pour les URL, couramment rencontrés dans les chemins.
4. Chaîne de requête (Groupe 4) : [?]?([^#\s`?]*)
- Objectif : Correspond de manière optionnelle à une chaîne de requête, commençant par n’importe quel caractère
?. Explication :
[?]?: Correspond de manière optionnelle à un?. (Les crochets ne sont pas strictement nécessaires, mais ils améliorent légèrement la lisibilité par rapport au double??très concis. Ils créent aussi un parallèle visuel avec le groupe de correspondance suivant, similaire :[#]?.)([^#\s`?]*): Correspond à zéro ou plusieurs caractères qui ne sont ni un dièse, ni un espace, ni un accent grave, ni un point d’interrogation.
5. Fragment (Groupe 5) : [#]?([^#\s’”`.,!]*)
- Objectif : Correspond de manière optionnelle à l’identifiant de fragment, commençant par un
#. Explication :
[#]?: Correspond de manière optionnelle à un#.([^#\s’”`.,!]*): Correspond à zéro ou plusieurs caractères qui ne sont pas de la ponctuation interdite ou des espaces.
🛠️ Exemple d’analyse
Voici comment exploiter cette regex monstrueuse avec un peu de JavaScript :
const text = `Check this out: https://example.com/path?query=123#sectionAnd also (ftp://files.server.org/index).Plus a weird one: custom-scheme://host/param;weird^stuff`;
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;
const matches = [ ...text.matchAll(urlRegex),].map((match) => match[0]);console.log("Extracted URLs:", matches);
const parts = [ ...text.matchAll(urlRegex),].map((match) => match.slice(1));console.log("Extracted Parts:", parts);[ "https://example.com/path?query=123#section", "ftp://files.server.org/index", "custom-scheme://host/param;weird^stuff"][ [ "https://", // Protocol "example.com", // Domain "/path", // Path "query=123", // Query "section" // Fragment ], [ "ftp://", // Protocol "files.server.org", // Domain "/index", // Path "", // Query "" // Fragment ], [ "custom-scheme://", // Protocol "host", // Domain "/param;weird^stuff", // Path "", // Query "" // Fragment ]]☑️ Étapes suivantes
Selon votre cas d’usage, vous devrez peut-être affiner cette regex ou ajouter des étapes de validation et de post-traitement.
Projets variés, besoins distincts
Les projets présentent des exigences et des enjeux de sécurité variés :
- Web Scraping : Valider les URL pour garantir leur accessibilité et leur fiabilité.
- Traitement des données : Extraire les URL de contenus générés par les utilisateurs tout en maintenant des contrôles de sécurité.
- Analyse de données : Filtrer les doublons ou les liens non pertinents à des fins de recherche ou de marketing.
- Applications côté utilisateur : Transformer automatiquement les URL en liens hypertextes dans les applications de chat ou les forums.
Post-traitement et validation
Une fois les URL candidates récupérées, appliquez des vérifications supplémentaires :
- Résolution DNS : Vérifier que les noms de domaine résolvent correctement.
- Contrôles de sécurité : Utiliser des services pour vérifier la réputation des domaines et réduire les risques liés aux sites malveillants ou au phishing.
- Règles spécifiques : Appliquer des filtres propres au projet (ex. : TLD autorisés, longueur maximale d’URL).
📝 Résumé
L’extraction de données textuelles semi-structurées est probablement la partie la plus gratifiante de la maîtrise des regex.
Voici un résumé des points clés à retenir :
- Utiliser un outil visuel pour rédiger, tester & comprendre vos expressions régulières.
- Découper le problème en sous-parties et les traiter séparément. À ce titre, les groupes de capture servent de jalons figuratifs pour structurer notre regex.
- Privilégier des expressions de correspondance larges, éviter une conformité stricte aux spécifications lors de l’ingestion de données.
- Appliquer des étapes de validation après l’extraction initiale est indispensable ; tenez toujours compte de la sécurité de votre projet et de ses contraintes spécifiques.
En suivant cette approche, vous pouvez extraire efficacement toute donnée textuelle semi-structurée, posant ainsi les bases d’un traitement et d’une validation ultérieurs.
📚 Pour aller plus loin
- N’hésitez pas à expérimenter avec la démo en ligne sur RegEx101.com !
- La question d’origine sur StackOverflow, ainsi qu’un lien vers ma réponse ici même.
- Documentation MDN sur les expressions régulières
- Techniques avancées de regex : Explorez les lookaheads, lookbehinds et autres motifs avancés pour une correspondance plus précise.
- RFC 3986 - Syntaxe générique des URI