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

Rust Regex无环视时,如何匹配单括号而非双括号内的单词?

解决Rust Regex无法匹配连续{...}结构的问题

这个问题我之前也碰到过,你的正则核心问题在于消耗了{前面的字符,导致连续的{these}{also}这类结构中,第二个{...}无法被捕获。原正则里的(?:[^{]|^)会吃掉{前面的非{字符(比如空格、前一个}),当匹配完{these}后,指针已经移到下一个{的位置,没有剩余字符能满足[^{]的匹配条件,自然就抓不到also了。

下面给你两个靠谱的解决方案:

方案1:先匹配所有{...},再用代码过滤转义项

既然Rust Regex不支持环视,我们可以换个思路:先把所有{...}结构都匹配出来,再通过代码判断哪些是需要保留的(排除被{{包裹的转义项)。这种方法不依赖正则的高级特性,兼容性更好。

extern crate regex;
use regex::Regex;

fn main() {
    // 匹配所有{...}结构,捕获内部的内容
    let exp = Regex::new(r"\{([^{}]*)\}").unwrap();
    let text = "{this} is a match, {{escaped}} is not, but {these}{also} are.";
    
    for capture in exp.captures_iter(text) {
        // 获取整个匹配项的起始位置,用来检查前一个字符
        let match_start = capture.get(0).unwrap().start();
        // 如果前一个字符是'{',说明这是转义的{{...}}里的内容,跳过
        if match_start > 0 && text.as_bytes()[match_start - 1] == b'{' {
            continue;
        }
        // 输出我们需要的捕获内容
        println!("{}", &capture[1]);
    }
    // 输出结果:this, these, also
}

方案2:用新版Regex的有限环视功能(推荐)

如果你能把项目里的regex crate升级到1.0及以上版本,其实它支持固定长度的负后向环视(单个字符的环视是支持的)。这时候我们可以直接用正则来过滤转义项,不需要额外的代码判断:

extern crate regex;
use regex::Regex;

fn main() {
    // (?<!\{) 负后向环视:确保{前面不是{
    // ([^{}]*) 捕获内部非{}的内容
    // (?!\}) 负前向环视:确保}后面不是}(可选,根据你的转义规则调整)
    let exp = Regex::new(r"(?<!\{)\{([^{}]*)\}(?!\})").unwrap();
    let text = "{this} is a match, {{escaped}} is not, but {these}{also} are.";
    
    for capture in exp.captures_iter(text) {
        println!("{}", &capture[1]);
    }
    // 输出结果:this, these, also
}

这个正则里的(?<!\{)是零宽度的负后向环视,它不会消耗任何字符,只是检查{前面是不是{,这样连续的{...}{...}就能被依次匹配到,完美解决你的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:14:23