Reguläre Ausdrücke in Rust mit Beispielen: in der Praxis
\n\nReguläre Ausdrücke (regex) sind ein mächtiges Werkzeug für die Textverarbeitung. In Rust ist die Arbeit mit regulären Ausdrücken trotz strenger Typisierung und Fokus auf Sicherheit dank der Crate regex effizient und komfortabel umgesetzt. In diesem Artikel werden wir uns ansehen, wie man reguläre Ausdrücke in Rust in der Praxis einsetzt: von der Installation bis zu komplexen Szenarien der Zeichenkettenverarbeitung.
Wir betrachten die grundlegenden Operationen: Suchen, Extrahieren, Ersetzen und Validieren. Alle Codebeispiele sind in Rust geschrieben und einsatzbereit.
\n\nInstallation und Einbindung der Regex-Crate
\n\nFür die Arbeit mit regulären Ausdrücken in Rust wird die externe, aber sehr beliebte Crate regex verwendet. Sie ist nicht in der Standardbibliothek enthalten, daher muss sie zum Projekt hinzugefügt werden.
Fügen Sie die Abhängigkeit in die Datei Cargo.toml ein:
[dependencies]\nregex = "1"\n\nDanach können die wichtigsten Typen im Code importiert werden:
\n\nuse regex::Regex;\n\nDie Crate regex kompiliert den regulären Ausdruck in einen endlichen Automaten, was eine hohe Leistung gewährleistet. Kompilierungsfehler des Musters werden zur Laufzeit (über Result) abgefangen, was den Code zuverlässig macht.
Grundlagen: Suche nach Übereinstimmungen in einer Zeichenkette
\n\nDer einfachste Weg, um zu prüfen, ob eine Zeichenkette einem Muster entspricht, ist die Verwendung der Methode is_match. Betrachten wir ein Beispiel zur Überprüfung des Vorhandenseins einer E-Mail-Adresse in einem Text.
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b").unwrap();\n let text = "Kontaktieren Sie uns unter support@example.com.";\n\n if re.is_match(text) {\n println!("E-Mail gefunden!");\n } else {\n println!("E-Mail nicht gefunden.");\n }\n}\n\nDie Methode Regex::new nimmt eine Zeichenkette mit dem Muster entgegen und gibt ein Result zurück. unwrap() wird hier der Einfachheit halber verwendet, aber im Produktionscode sollten Fehler korrekt behandelt werden.
Zur Suche aller Übereinstimmungen wird die Methode find_iter verwendet, die einen Iterator über Match-Objekte zurückgibt:
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"\\d+").unwrap();\n let text = "Preise: 100, 250 und 500 Rubel.";\n\n for mat in re.find_iter(text) {\n println!("Zahl gefunden: {}", mat.as_str());\n }\n}\n\nDieser Code gibt Folgendes aus:
\n\nZahl gefunden: 100\nZahl gefunden: 250\nZahl gefunden: 500\n\nDatenextraktion mit Erfassungsgruppen
\n\nErfassungsgruppen (capturing groups) ermöglichen es, nicht nur die gesamte Übereinstimmung, sondern auch einzelne Teile davon zu extrahieren. Zum Beispiel das Parsen eines Datums im Format "TT-MM-JJJJ".
\n\nuse regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\d{2})-(\\d{2})-(\\d{4})").unwrap();\n let text = "Heute ist der 15-03-2024.";\n\n if let Some(caps) = re.captures(text) {\n println!("Tag: {}", &caps[1]);\n println!("Monat: {}", &caps[2]);\n println!("Jahr: {}", &caps[3]);\n }\n}\n\nDie Indizierung der Gruppen beginnt bei 1 (Gruppe 0 ist die gesamte Übereinstimmung). Die Methode captures gibt ein Option<Captures> zurück. Wenn eine Übereinstimmung gefunden wurde, können wir über den Index auf die Gruppen zugreifen.
Zur Extraktion aller Vorkommen mit Gruppen wird captures_iter verwendet:
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\w+)@(\\w+)\\.(\\w+)").unwrap();\n let text = "E-Mails: user@host.com, admin@site.org";\n\n for caps in re.captures_iter(text) {\n println!("Benutzername: {}, Domain: {}, Zone: {}", &caps[1], &caps[2], &caps[3]);\n }\n}\n\nDieser Ansatz ist unverzichtbar beim Parsen von Logs, Konfigurationsdateien oder beim Extrahieren strukturierter Daten aus unstrukturiertem Text.
\n\nTextersetzung nach Muster
\n\nDie Crate regex