You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust正则匹配单数字(含单词形式):重叠字符匹配问题求助

解决Rust regex中重叠数字单词的匹配问题

你的问题出在普通正则的贪婪匹配特性:当遇到eightwo这类重叠字符串时,正则会优先匹配更长的eight,匹配完成后消耗掉对应的字符,剩下的wo无法触发two的匹配。要解决这个问题,有两种可行方案:

方案一:使用正向预查的正则表达式

Rust的regex库支持正向预查(零宽度断言),它不会消耗匹配到的字符,能让正则在同一个位置多次检查不同的匹配模式。修改后的正则如下:

let re = Regex::new(r"(?=([0-9]|one|two|three|four|five|six|seven|eight|nine|ten))").unwrap();

原理说明

(?=...)是正向预查断言,它仅验证当前位置后方是否存在匹配的模式,但不会移动正则的匹配指针。这样遍历字符串时,每个字符位置都会被检查是否能匹配数字或数字单词,自然就能捕获到eightwo中的eight和two。

提取匹配结果

需要遍历所有捕获组的内容(预查内的括号是捕获组):

let input = "eightwo";
for cap in re.captures_iter(input) {
    if let Some(match_str) = cap.get(1) {
        println!("匹配到: {}", match_str.as_str());
    }
}

运行后会输出:

匹配到: eight
匹配到: two

方案二:手动遍历字符串(非正则方案)

如果觉得正则的写法不够直观,也可以通过滑动窗口遍历字符串,逐个位置检查匹配情况,逻辑更清晰:

fn extract_all_digits(s: &str) -> Vec<&str> {
    let digit_words = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
    let mut results = Vec::new();
    let chars: Vec<char> = s.chars().collect();
    let mut idx = 0;

    while idx < chars.len() {
        // 检查当前字符是否是数字
        if chars[idx].is_ascii_digit() {
            results.push(&s[idx..idx+1]);
            idx += 1;
            continue;
        }

        // 检查当前位置是否匹配某个数字单词
        for &word in &digit_words {
            let word_len = word.len();
            if idx + word_len <= chars.len() && &s[idx..idx+word_len] == word {
                results.push(word);
                break;
            }
        }

        idx += 1;
    }

    results
}

// 使用示例
fn main() {
    let test_str = "eightwo";
    let digits = extract_all_digits(test_str);
    println!("所有匹配结果: {:?}", digits); // 输出 ["eight", "two"]
}

原理说明

通过逐个位置遍历字符串:

  1. 先检查当前字符是否是数字,是则直接加入结果;
  2. 否则检查从当前位置开始是否能匹配任意数字单词,匹配到就加入结果;
  3. 每次只移动一个字符的位置,确保重叠的字符串能被多次检查。

内容的提问来源于stack exchange,提问作者dsadsadsadas dsadasdasda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:00:11