微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不克隆数据的情况下循环调用正则表达式

如何解决如何在不克隆数据的情况下循环调用正则表达式

我正在编写一些代码来对内容调用 N 个正则表达式,如果可能的话,我想避免一直克隆字符串,因为并非每个正则表达式实际上都是匹配的。这甚至可能吗? 我试图做的代码是这样的:

use std::borrow::Cow;
use regex::Regex;

fn main() {
    let test = "abcde";
    let regexes = vec![
        (Regex::new("a").unwrap(),"b"),(Regex::new("b").unwrap(),"c"),(Regex::new("z").unwrap(),"-"),];
    let mut contents = Cow::Borrowed(test);
    
    for (regex,new_value) in regexes {
        contents = regex.replace_all(&contents,new_value);
    }
    println!("{}",contents);
}

预期的结果将是 cccde(如果有效)和两个克隆。但要让它发挥作用,我必须在每次迭代中继续克隆:

fn main() {
    let test = "abcde";
    let regexes = vec![
        (Regex::new("a").unwrap(),];
    let mut contents = test.to_string();

    for (regex,new_value).to_string();
    }
    println!("{}",contents);
}

然后输出 cccde 但有 3 个克隆。 是否有可能以某种方式避免它?我知道我可以调用每个正则表达式并重新绑定返回值,但我无法控制可能出现的正则表达式数量。 提前致谢!

编辑 1

想看真实代码的人: 它正在执行 O(n^2) 正则表达式操作。 它从这里开始 https://github.com/jaysonsantos/there-i-fixed-it/blob/ad214a27606bc595d80bb7c5968d4f80ac032e65/src/plan/executor.rs#L185-L192 并称之为 https://github.com/jaysonsantos/there-i-fixed-it/blob/main/src/plan/mod.rs#L107-L115

编辑 2 这是带有已接受答案的新代码 https://github.com/jaysonsantos/there-i-fixed-it/commit/a4f5916b3e80749de269efa219b0689cb08551f2

解决方法

您可以通过在字符串被替换时使用字符串作为字符串的持久所有者来实现,并在每次迭代时检查返回的 Cow 是否被拥有。如果它被拥有,您就知道替换成功,因此您将 Cow 拥有的字符串分配到循环变量中。

    let mut contents = test.to_owned();
    
    for (regex,new_value) in regexes {
        let new_contents = regex.replace_all(&contents,new_value);
        if let Cow::Owned(new_string) = new_contents {
            contents = new_string;
        }
    }

请注意,Rust 中的赋值默认是“移动”——这意味着 new_string 的值被移动而不是复制到 contents 中。

Playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。