Regex: Vom Anfänger zum Profi
URL-ähnliche Strings extrahieren & parsen mit einem einzigen Regex
Inhaltsverzeichnis
- 🚀 Einleitung
- 🔍 URLs aus Text extrahieren
- 🛳️ Der 120+ Byte Regex
- 🧩 Schritt-für-Schritt-Zerlegung
- 🛠️ Parsing-Beispiel
- ☑️ Nächste Schritte
- 📝 Zusammenfassung
- 📚 Weiterführende Literatur
TL;DR: Springen Sie direkt zum 120+ Byte Regex.
🚀 Einleitung
Das Extrahieren von URLs aus rohem Text kann sich schnell in ein mühsames Whack-a-Mole-Spiel verwandeln. Interpunktion, umgebende Klammern und mehrdeutige Formatierungen arbeiten zusammen, um Ihre Bemühungen zu vereiteln. Ob Sie einen Web-Scraper, einen Datenanalysator oder eine Chat-Anwendung entwickeln – das präzise Extrahieren von URLs ist unverzichtbar.
In diesem Beitrag gehen wir das Problem direkt an und setzen auf einen flexiblen, zweistufigen Ansatz. Unser Ziel ist es, zunächst alle potenziellen URL-ähnlichen Strings zu erfassen und die Validierung einem nachgelagerten Schritt zu überlassen.
💡 Hinweis: Dieses Muster dient nicht der Validierung von URLs! Es ist bewusst tolerant gegenüber Interpunktion und Tippfehlern.
🔍 Ziel: URLs aus Text extrahieren
Beim Extrahieren von URLs aus rohem Text bewährt sich ein zweistufiger Ansatz:
- Alles URL-ähnliche erfassen: Ein weites Netz werfen, um alle Strings zu sammeln, die möglicherweise URLs sind. Genau hier kommt unser „120-Byte-Regex“ ins Spiel.
- Validieren: Sobald diese Kandidaten erfasst sind, nutzen Sie sekundäre Prüfungen (z. B. DNS-Auflösung, Abgleich mit bekannten Domains), um ungültige Einträge herauszufiltern.
Die Herausforderung visualisieren
Begriffe wie extract und parse werden oft synonym verwendet, bezeichnen jedoch unterschiedliche Prozesse. Das Extrahieren von URLs bedeutet, potenzielle URLs aus einem größeren Textkorpus zu identifizieren und zu erfassen. Das Parsen hingegen zerlegt diese URLs in ihre Einzelkomponenten.
Wenn ich von Parsing oder „URL-Teilen“ spreche, meine ich folgende Komponenten:
Klicken Sie, um einen Screenshot der Substring-Matches in RegEx101 zu sehen.
Bevor wir zu tief in die Regex einsteigen, nutzen wir ein visuelles Tool, um zu prüfen, wie gut mein Muster mehrere Treffer erfasst:

Die 120+ Byte Regex
Im Folgenden finden Sie eine kompakte Regex, die URLs in einem einzigen Durchlauf extrahiert und parst. Sie unterstützt verschiedene Protokolle, Domains, Pfade sowie optionale Query- und Fragment-Bereiche.
Keine Sorge – wir zerlegen das Schritt für Schritt!
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'"`\.,!]*)Teilt die wildesten Regex-Patterns, die ihr je gesehen (oder selbst verfasst) habt, in den Kommentaren unten! 🚀
🧩 Schritt für Schritt zerlegt
Wir zerlegen die Regex in ihre Komponenten, um den Aufbau zu verstehen:
1. Protokoll (Gruppe 1): ([-.a-z0-9]+:/{1,3})
- Zweck: Erfasst den Protokollteil der URL (z. B.
http://,ftp://,custom-scheme://). Erklärung:
[-.a-z0-9]+: Stimmt auf mindestens einen Kleinbuchstaben, eine Ziffer, einen Bindestrich oder einen Punkt überein (häufig in Protokoll-Schemata).:/{1,3}: Stimmt auf einen Doppelpunkt, gefolgt von einem bis drei Schrägstrichen, überein (:/,://oder:///).
2. Domain (Gruppe 2): ([^-/.[](|)s?][^`/s]?]+)
- Zweck: Erfasst den Domain- oder Hostteil der URL.
Erklärung:
[^-/.[](|)\s?]: Stimmt auf jedes Zeichen außer den angegebenen Sonderzeichen und Leerzeichen überein.[^`/\s]?]+: Stimmt auf mindestens ein Zeichen außer Backticks, Schrägstrichen, Leerzeichen oder schließenden eckigen Klammern überein.
3. Pfad (Gruppe 3): ([-_a-z0-9!@$%^&*()=+;/~\.]*)
- Zweck: Stimmt auf die Pfadkomponente der URL überein.
Erklärung:
[-_a-z0-9!@$%^&()=+;/~.]: Stimmt auf null oder mehr URL-sichere Zeichen überein, die typischerweise in Pfaden vorkommen.
4. Query (Gruppe 4): [?]?([^#\s`?]*)
- Zweck: Stimmt optional auf eine Query-Zeichenkette überein, die mit einem beliebigen
?-Zeichen beginnt. Erklärung:
[?]?: Stimmt optional auf ein?überein. (Die eckigen Klammern sind nicht zwingend erforderlich, erhöhen jedoch die Lesbarkeit gegenüber der extrem knappen Doppelung??. Zudem schaffen sie eine visuelle Parallele zur (ähnlichen) nächsten Matching-Gruppe[#]?.)([^#\s`?]*): Stimmt auf null oder mehr Zeichen überein, die kein Hash, Leerzeichen, Backtick oder Fragezeichen sind.
5. Fragment (Gruppe 5): [#]?([^#\s’”`.,!]*)
- Zweck: Stimmt optional auf den Fragment-Bezeichner überein, der mit einem
#beginnt. Erklärung:
[#]?: Stimmt optional auf ein#überein.([^#\s’”`.,!]*): Stimmt auf null oder mehr Zeichen überein, die keine nicht erlaubten Satzzeichen oder Leerzeichen enthalten.
🛠️ Parsing-Beispiel
So setzen Sie diesen Regex-Monster mit etwas JavaScript in die Praxis um:
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://", // Protokoll "example.com", // Domain "/path", // Pfad "query=123", // Query "section" // Fragment ], [ "ftp://", // Protokoll "files.server.org", // Domain "/index", // Pfad "", // Query "" // Fragment ], [ "custom-scheme://", // Protokoll "host", // Domain "/param;weird^stuff", // Pfad "", // Query "" // Fragment ]]☑️ Nächste Schritte
Je nach Anwendungsfall müssen Sie diesen Regex möglicherweise verfeinern oder zusätzliche Validierungs- und Nachbearbeitungsschritte einfügen.
Unterschiedliche Projekte, unterschiedliche Anforderungen
Projekte unterscheiden sich in ihren Anforderungen und Sicherheitsbedenken:
- Web Scraping: URLs validieren, um Erreichbarkeit und Vertrauenswürdigkeit sicherzustellen.
- Datenverarbeitung: URLs aus nutzergenerierten Inhalten extrahieren, dabei Sicherheitsaspekte wahren.
- Datenanalyse: Duplikate oder irrelevante Links für Forschungs- oder Marketingzwecke herausfiltern.
- Anwendungen mit Benutzeroberfläche: URLs in Chat-Apps oder Foren automatisch verlinken.
Nachbearbeitung und Validierung
Nach dem Sammeln potenzieller URLs sind zusätzliche Prüfungen erforderlich:
- DNS-Lookup: Prüfen, ob Domains tatsächlich auflösbar sind.
- Sicherheitsprüfungen: Dienste einsetzen, um bösartige oder Phishing-Websites zu identifizieren.
- Eigene Regeln: Projektspezifische Filter anwenden (z. B. erlaubte TLDs, maximale URL-Länge).
📝 Zusammenfassung
Das Extrahieren semistrukturierter String-Daten ist vielleicht der befriedigendste Aspekt der Regex-Meisterschaft.
Hier ist eine Zusammenfassung der wichtigsten Erkenntnisse:
- Nutze ein visuelles Tool zum Schreiben, Testen und Verstehen deiner Regex-Muster.
- Zerlege die Herausforderung in einzelne Teile und bearbeite jeden separat. In gewisser Weise dienen Capture Groups als figurative ‘Wegweiser’ für unseren Regex.
- Nutze ‘lockere’ Match-Ausdrücke, vermeide strikte Spezifikationskonformität bei der Datenaufnahme.
- Validierungsschritte nach der initialen Extraktion sind essenziell—berücksichtige dabei stets die Sicherheit und die spezifischen Anforderungen deines Projekts.
Die Einhaltung dieser Schritte ermöglicht die effektive Extraktion beliebiger semistrukturierter String-Daten und schafft die Voraussetzung für nachgelagerte Verarbeitung und Validierung.
📚 Weiterführende Ressourcen
- Probier die Live-Demo auf RegEx101.com unbedingt aus!
- Die ursprüngliche StackOverflow-Frage sowie ein Link zu meiner Antwort direkt hier.
- MDN-Dokumentation zu Regulären Ausdrücken
- Fortgeschrittene Regex-Techniken: Erkunde Lookaheads, Lookbehinds und weitere fortgeschrittene Muster für präzisere Matches.
- RFC 3986 - URI Generic Syntax