dev_tool/
re_util.rs

1use regex::Regex;
2
3/// 正则工具,如匹配、捕获第一个、捕获所有等
4pub struct ReUtil;
5
6impl ReUtil {
7    /// 检查文本是否匹配给定的正则表达式模式
8    ///
9    /// # 参数
10    /// * `re` - 正则表达式模式字符串
11    /// * `text` - 要检查的文本字符串
12    ///
13    /// # 返回值
14    /// 如果文本匹配正则表达式模式则返回true,否则返回false
15    ///
16    /// # Panics
17    /// 当正则表达式模式无效时会panic
18    pub fn is_match(re: &str, text: &str) -> bool {
19        // 编译正则表达式模式
20        let re = Regex::new(re).unwrap();
21        // 执行匹配检查
22        re.is_match(text)
23    }
24
25    /// 在给定文本中查找第一个匹配正则表达式的子串
26    ///
27    /// # 参数
28    /// * `re` - 要匹配的正则表达式字符串
29    /// * `text` - 要搜索的文本内容
30    ///
31    /// # 返回值
32    /// 返回第一个匹配的子串引用,如果没有匹配则返回None
33    ///
34    /// # 示例
35    /// ```
36    /// let result = find_first(r"\d+", "abc123def456");
37    /// assert_eq!(result, Some("123"));
38    /// ```
39    pub fn find_first<'a>(re: &str, text: &'a str) -> Option<&'a str> {
40        // 编译正则表达式
41        let re = Regex::new(re).unwrap();
42        // 查找第一个匹配项
43        if let Some(captured) = re.find(text) {
44            let result = captured.as_str();
45            return Some(result);
46        }
47        None
48    }
49
50    /// 在给定文本中查找所有匹配正则表达式的子串
51    ///
52    /// # 参数
53    /// * `re` - 要使用的正则表达式字符串
54    /// * `text` - 要搜索的文本
55    ///
56    /// # 返回值
57    /// 返回包含所有匹配子串的字符串向量
58    ///
59    /// # 示例
60    /// ```
61    /// let matches = find_all(r"\d+", "abc123def456");
62    /// assert_eq!(matches, vec!["123", "456"]);
63    /// ```
64    pub fn find_all(re: &str, text: &str) -> Vec<String> {
65        // 编译正则表达式,如果编译失败则panic
66        let re = Regex::new(re).unwrap();
67        let mut vec = Vec::new();
68
69        // 遍历所有匹配项,提取完整匹配并添加到结果向量中
70        for cap in re.captures_iter(text) {
71            let s = cap[0].to_string();
72            vec.push(s);
73        }
74
75        vec
76    }
77
78    /// 使用正则表达式匹配文本并返回所有捕获组的字符串列表
79    ///
80    /// # 参数
81    /// * `re` - 正则表达式字符串
82    /// * `text` - 要匹配的文本字符串
83    ///
84    /// # 返回值
85    /// 返回包含所有捕获组匹配结果的字符串向量,如果没有匹配则返回空向量
86    ///
87    /// # 示例
88    /// ```
89    /// let result = captures(r"^images_(\d{4}-\d{2}-\d{2})_([a-zA-Z0-9]+).jpg$", "images_2025-01-01_xxxx.jpg");
90    /// assert_eq!(result, vec!["images_2025-01-01_xxxx.jpg", "2025-01-01", "xxxx"]);
91    /// ```
92    pub fn captures(re: &str, text: &str) -> Vec<String> {
93        let re = Regex::new(re).unwrap();
94        let mut vec = Vec::new();
95        let caps = re.captures(text);
96
97        // 遍历所有捕获组并将其转换为字符串添加到结果向量中
98        if let Some(caps) = caps {
99            for cap in caps.iter() {
100                if let Some(cap) = cap {
101                    let s = cap.as_str().to_string();
102                    vec.push(s);
103                }
104            }
105        }
106
107        vec
108    }
109}
110
111#[cfg(test)]
112mod tests {
113
114    #[test]
115    fn test_re_util() {
116        let re = r"^images_(\d{4}-\d{2}-\d{2})_([a-zA-Z0-9]+).jpg$";
117        let text = "images_2025-01-01_xxxx.jpg";
118        let vec = super::ReUtil::captures(re, text);
119        println!("{:?}", vec);
120    }
121}