Expressions régulières en Rust avec exemples : en pratique
\n\nLes expressions régulières (regex) sont un outil puissant pour travailler avec du texte. En Rust, malgré un typage strict et un accent mis sur la sécurité, le travail avec les expressions régulières est implémenté de manière efficace et pratique grâce à la crate regex. Dans cet article, nous allons voir comment utiliser les expressions régulières en Rust en pratique : de l'installation aux scénarios complexes de traitement de chaînes.
Nous aborderons les opérations principales : recherche, extraction, remplacement et validation. Tous les exemples de code sont écrits en Rust et prêts à être utilisés.
\n\nInstallation et ajout de la crate regex
\n\nPour travailler avec les expressions régulières en Rust, on utilise une crate tierce, mais très populaire, appelée regex. Elle ne fait pas partie de la bibliothèque standard, il faut donc l'ajouter au projet.
Ajoutez la dépendance dans le fichier Cargo.toml :
[dependencies]\nregex = "1"\n\nEnsuite, dans le code, vous pouvez importer les types principaux :
\n\nuse regex::Regex;\n\nLa crate regex compile l'expression régulière en un automate fini, ce qui garantit des performances élevées. Les erreurs de compilation du motif sont détectées à l'exécution (via Result), ce qui rend le code fiable.
Les bases : recherche de correspondances dans une chaîne
\n\nLa façon la plus simple de vérifier si une chaîne correspond à un motif est d'utiliser la méthode is_match. Voici un exemple de vérification de la présence d'une adresse email dans un texte.
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 = "Contactez-nous à l'adresse support@example.com.";\n\n if re.is_match(text) {\n println!("Email trouvé !");\n } else {\n println!("Email non trouvé.");\n }\n}\n\nLa méthode Regex::new prend une chaîne contenant le motif et retourne un Result. unwrap() est utilisé ici par simplicité, mais dans un code de production, il faut gérer les erreurs correctement.
Pour rechercher toutes les correspondances, on utilise la méthode find_iter, qui retourne un itérateur sur des objets Match :
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"\\d+").unwrap();\n let text = "Prix : 100, 250 et 500 roubles.";\n\n for mat in re.find_iter(text) {\n println!("Nombre trouvé : {}", mat.as_str());\n }\n}\n\nCe code affichera :
\n\nNombre trouvé : 100\nNombre trouvé : 250\nNombre trouvé : 500\n\nExtraction de données avec des groupes de capture
\n\nLes groupes de capture (capturing groups) permettent d'extraire non seulement la correspondance entière, mais aussi ses parties individuelles. Par exemple, l'analyse d'une date au format "jj-mm-aaaa".
\n\nuse regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\d{2})-(\\d{2})-(\\d{4})").unwrap();\n let text = "Aujourd'hui, nous sommes le 15-03-2024.";\n\n if let Some(caps) = re.captures(text) {\n println!("Jour : {}", &caps[1]);\n println!("Mois : {}", &caps[2]);\n println!("Année : {}", &caps[3]);\n }\n}\n\nL'indexation des groupes commence à 1 (le groupe 0 correspond à la correspondance entière). La méthode captures retourne une Option<Captures>. Si une correspondance est trouvée, on peut accéder aux groupes via l'index.
Pour extraire toutes les occurrences avec des groupes, on utilise captures_iter :
use regex::Regex;\n\nfn main() {\n let re = Regex::new(r"(\\w+)@(\\w+)\\.(\\w+)").unwrap();\n let text = "emails : user@host.com, admin@site.org";\n\n for caps in re.captures_iter(text) {\n println!("Identifiant : {}, domaine : {}, zone : {}", &caps[1], &caps[2], &caps[3]);\n }\n}\n\nCette approche est indispensable pour l'analyse de journaux, de fichiers de configuration ou pour l'extraction de données structurées à partir de texte non structuré.
\n\nRemplacement de texte selon un motif
\n\nLa crate regex