Rust 正则表达式完全指南

server/2025/1/15 8:07:19/

Rust 正则表达式完全指南

Rust通过 regex crate提供正则表达式支持。本指南将详细介绍Rust中正则表达式的使用方法、性能优化和最佳实践。

1. 基础知识

1.1 添加依赖

Cargo.toml 中添加:

[dependencies]
regex = "1.10.2"

1.2 基本使用

rust">use regex::Regex;fn main() {// 创建正则表达式let re = Regex::new(r"\d+").unwrap();// 基本匹配let text = "123 456 789";// 检查是否匹配assert!(re.is_match(text));// 查找第一个匹配if let Some(mat) = re.find(text) {println!("Found match: {}", mat.as_str()); // "123"}// 查找所有匹配for mat in re.find_iter(text) {println!("Match: {}", mat.as_str());}
}

1.3 编译时正则表达式

使用 lazy_static 优化性能:

rust">use lazy_static::lazy_static;
use regex::Regex;lazy_static! {static ref EMAIL_RE: Regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();static ref PHONE_RE: Regex = Regex::new(r"^1[3-9]\d{9}$").unwrap();
}fn is_valid_email(email: &str) -> bool {EMAIL_RE.is_match(email)
}fn is_valid_phone(phone: &str) -> bool {PHONE_RE.is_match(phone)
}

2. 正则表达式语法

2.1 字符匹配

rust">use regex::Regex;fn main() {let text = "Rust 2021 is awesome! Price: $99.99";// 匹配数字let digits = Regex::new(r"\d+").unwrap();for mat in digits.find_iter(text) {println!("Number: {}", mat.as_str());}// 匹配单词let words = Regex::new(r"\w+").unwrap();for mat in words.find_iter(text) {println!("Word: {}", mat.as_str());}// 匹配空白字符let spaces = Regex::new(r"\s+").unwrap();let parts: Vec<&str> = spaces.split(text).collect();println!("Parts: {:?}", parts);// 自定义字符类let vowels = Regex::new(r"[aeiou]").unwrap();for mat in vowels.find_iter(text) {println!("Vowel: {}", mat.as_str());}
}

2.2 捕获组

rust">use regex::Regex;fn main() {let text = "John Smith, Jane Doe, Bob Johnson";let re = Regex::new(r"(\w+)\s(\w+)").unwrap();// 使用命名捕获组let re_named = Regex::new(r"(?P<first>\w+)\s(?P<last>\w+)").unwrap();// 基本捕获for caps in re.captures_iter(text) {println!("Full name: {}", &caps[0]);println!("First name: {}", &caps[1]);println!("Last name: {}", &caps[2]);}// 命名捕获for caps in re_named.captures_iter(text) {println!("First: {}, Last: {}",&caps["first"],&caps["last"]);}
}

3. 高级特性

3.1 替换操作

rust">use regex::Regex;fn main() {let text = "My phone is 123-456-7890";let re = Regex::new(r"\d{3}-\d{3}-\d{4}").unwrap();// 简单替换let result = re.replace(text, "XXX-XXX-XXXX");println!("{}", result);// 替换所有匹配let result = re.replace_all(text, "XXX-XXX-XXXX");println!("{}", result);// 使用回调函数替换let result = re.replace_all(text, |caps: &regex::Captures| {format!("PHONE({})", &caps[0])});println!("{}", result);
}

3.2 正则表达式集合

rust">use regex::RegexSet;fn main() {// 创建正则表达式集合let set = RegexSet::new(&[r"\w+@\w+\.\w+",    // 邮箱r"\d{3}-\d{3}-\d{4}", // 电话r"\d{5}",           // 邮编]).unwrap();let text = "Contact: john@example.com, 123-456-7890, 12345";// 检查哪些模式匹配let matches: Vec<_> = set.matches(text).into_iter().collect();println!("Matching patterns: {:?}", matches);
}

4. 实用工具

4.1 验证器

rust">use regex::Regex;
use lazy_static::lazy_static;lazy_static! {static ref VALIDATORS: Validators = Validators::new();
}pub struct Validators {email: Regex,phone: Regex,password: Regex,url: Regex,
}impl Validators {fn new() -> Self {Self {email: Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap(),phone: Regex::new(r"^1[3-9]\d{9}$").unwrap(),password: Regex::new(r"^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$").unwrap(),url: Regex::new(r"^https?://[^\s/$.?#].[^\s]*$").unwrap(),}}pub fn is_valid_email(&self, email: &str) -> bool {self.email.is_match(email)}pub fn is_valid_phone(&self, phone: &str) -> bool {self.phone.is_match(phone)}pub fn is_valid_password(&self, password: &str) -> bool {self.password.is_match(password)}pub fn is_valid_url(&self, url: &str) -> bool {self.url.is_match(url)}
}// 使用示例
fn validate_user_input(email: &str, phone: &str) -> Result<(), String> {if !VALIDATORS.is_valid_email(email) {return Err("Invalid email format".to_string());}if !VALIDATORS.is_valid_phone(phone) {return Err("Invalid phone format".to_string());}Ok(())
}

4.2 文本处理器

rust">use regex::Regex;
use lazy_static::lazy_static;lazy_static! {static ref TEXT_PROCESSOR: TextProcessor = TextProcessor::new();
}pub struct TextProcessor {url: Regex,html_tag: Regex,whitespace: Regex,
}impl TextProcessor {fn new() -> Self {Self {url: Regex::new(r"https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+[^\s]*").unwrap(),html_tag: Regex::new(r"<[^>]+>").unwrap(),whitespace: Regex::new(r"\s+").unwrap(),}}pub fn extract_urls(text: &str) -> Vec<String> {TEXT_PROCESSOR.url.find_iter(text).map(|m| m.as_str().to_string()).collect()}pub fn strip_html_tags(html: &str) -> String {TEXT_PROCESSOR.html_tag.replace_all(html, "").to_string()}pub fn clean_whitespace(text: &str) -> String {TEXT_PROCESSOR.whitespace.replace_all(text.trim(), " ").to_string()}
}

5. 性能优化

5.1 编译优化

rust">use regex::RegexBuilder;fn create_optimized_regex() -> regex::Regex {RegexBuilder::new(r"\b\w+\b").case_insensitive(true).multi_line(true).dot_matches_new_line(true).build().unwrap()
}

5.2 性能考虑

rust">use regex::Regex;
use lazy_static::lazy_static;// 1. 使用 lazy_static 避免重复编译
lazy_static! {static ref PATTERN: Regex = Regex::new(r"\d+").unwrap();
}// 2. 使用精确的模式
fn good_pattern() {let specific = Regex::new(r"^\d{3}$").unwrap();  // 更好let general = Regex::new(r"\d+").unwrap();       // 较差
}// 3. 避免回溯
fn avoid_backtracking() {let bad = Regex::new(r".*foo.*").unwrap();       // 可能导致回溯let good = Regex::new(r"[^/]*foo[^/]*").unwrap(); // 更好的选择
}// 4. 使用非捕获组
fn use_non_capturing_groups() {let capturing = Regex::new(r"(foo)").unwrap();     // 捕获组let non_capturing = Regex::new(r"(?:foo)").unwrap(); // 非捕获组
}

6. 错误处理

rust">use regex::Regex;
use std::error::Error;fn compile_regex(pattern: &str) -> Result<Regex, Box<dyn Error>> {match Regex::new(pattern) {Ok(re) => Ok(re),Err(e) => Err(Box::new(e)),}
}fn safe_regex_match(pattern: &str, text: &str) -> Result<bool, Box<dyn Error>> {let re = compile_regex(pattern)?;Ok(re.is_match(text))
}// 使用示例
fn main() -> Result<(), Box<dyn Error>> {match safe_regex_match(r"\d+", "123") {Ok(true) => println!("Pattern matched!"),Ok(false) => println!("Pattern did not match."),Err(e) => eprintln!("Error: {}", e),}Ok(())
}

7. 测试

rust">#[cfg(test)]
mod tests {use super::*;#[test]fn test_email_validation() {assert!(VALIDATORS.is_valid_email("test@example.com"));assert!(!VALIDATORS.is_valid_email("invalid.email"));assert!(VALIDATORS.is_valid_email("user@domain.co.uk"));}#[test]fn test_phone_validation() {assert!(VALIDATORS.is_valid_phone("13812345678"));assert!(!VALIDATORS.is_valid_phone("12345678"));assert!(!VALIDATORS.is_valid_phone("23812345678"));}#[test]fn test_text_processing() {let html = "<p>Hello</p><div>World</div>";assert_eq!(TextProcessor::strip_html_tags(html),"HelloWorld");let text = "  multiple   spaces   here  ";assert_eq!(TextProcessor::clean_whitespace(text),"multiple spaces here");}
}

总结

Rust的正则表达式实现具有以下特点:

  1. 高性能的正则表达式引擎
  2. 安全的API设计
  3. 丰富的编译时优化选项
  4. 完整的Unicode支持

最佳实践:

  1. 使用 lazy_static 缓存编译后的正则表达式
  2. 选择合适的正则表达式构建方式
  3. 注意性能优化和内存使用
  4. 做好错误处理
  5. 编写完整的测试用例

注意事项:

  1. 正则表达式编译有开销,应该重用
  2. 使用适当的模式避免回溯
  3. 考虑使用 RegexSet 处理多个模式
  4. 注意字符串的生命周期

记住:在Rust中使用正则表达式时,要充分利用Rust的类型系统和所有权机制,确保代码既高效又安全。合理使用 lazy_static 和其他优化技术可以显著提高性能。


http://www.ppmy.cn/server/158494.html

相关文章

什么是共模电感_共模电感的特性

共模电感&#xff08;Common Mode Inductor&#xff09;&#xff0c;也称为共模扼流圈&#xff0c;是一种特殊的电感器件&#xff0c;主要用于抑制共模噪声&#xff08;Common Mode Noise&#xff09;。以下是关于共模电感的详细解释及其特性&#xff1a; 定义 共模电感是一种…

Oracle概述

Oracle概述 Oracle是世界领先的信息管理软件开发商,因其复杂的关系数据库产品而闻名。以下是对Oracle的详细介绍: 一、公司背景与概况 成立时间与地点 :Oracle公司成立于1977年,总部位于美国加州红木滩市(Redwood Shores)。创始人 :由劳伦斯埃里森(Lawrence J. Ellis…

Linux SUID提权

文章目录 1. SUID/SGID2. 查找SUID文件3. SUID/SGID提权3.1 SUID配置不当3.2 SUID systemctl提权3.3 $PATH变量劫持 参考 1. SUID/SGID SUID&#xff08;Set User ID&#xff09;意味着如果某个用户对属于自己的文件设置了这种权限&#xff0c;那么其他用户在执行这一脚本时也…

蓝桥杯历届真题 #分布式队列 (Java,C++)

文章目录 题目解读[蓝桥杯 2024 省 Java B] 分布式队列题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路完整代码 题目解读 题目链接 [蓝桥杯 2024 省 Java B] 分布式队列 题目描述 小蓝最近学习了一种神奇的队列&#xff1a;分布式队列。简单来说&#x…

android wifi framework与wpa_supplicant的交互

android frmework直接与wpa_supplicant进行交互&#xff0c;使用aidl或者hidl 二、事件 framework注册事件的地方&#xff1a; packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…

redis缓存篇知识点总结

1.缓存雪崩 当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃 发生缓存雪崩有两…

STM32-PWR电源控制

1.0 定义 PWR&#xff08;Power Control&#xff09;电源控制 PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上升到PVD阀…

【面试题】技术场景 4、负责项目时遇到的棘手问题及解决方法

工作经验一年以上程序员必问问题 面试题概述 问题为在负责项目时遇到的棘手问题及解决方法&#xff0c;主要考察开发经验与技术水平&#xff0c;回答不佳会影响面试印象。提供四个回答方向&#xff0c;准备其中一个方向即可。 1、设计模式应用方向 以登录为例&#xff0c;未…