多次遍历一个字符串,同时替换该字符串的某些部分

Going through a string multiple times while replacing parts of that string

提问人:Patrik Holub 提问时间:10/30/2023 最后编辑:cafce25Patrik Holub 更新时间:10/31/2023 访问量:87

问:

我有看起来像这样的字符串.删除了空格字符。 现在我需要找到所有可解决的部分并用其他东西替换它们。(我选择了,每次替换的增量)"((a<=b)||(c&&(d==a))""[i]"i

因此,我希望字符串会像这样变化,⇒ ⇒ ⇒我还需要捕获各个部分。到目前为止,我已经编写了这个函数,并使用正则表达式EXPR_RE来查找和捕获:"((a<=b)||(c&&(d==a))""([0]||(c&&[1]))""([0]||[2])""[3]"

fn my_replace(in_str: &str) -> ([&str; 64], [[&str; 2]; 64]) {
    let mut operators: [&str; 64] = [""; 64];
    let mut operands: [[&str; 2]; 64] = [[""; 2]; 64];

    lazy_static! {
        static ref EXPR_RE: Regex =
            Regex::new(r"(\[?[A-Za-z0-9]+\]?)(==|&&|\|\||<=|!)(\[?[A-Za-z0-9]+\]?)").unwrap();
    }
    let mut i: usize = 0;
    let mut repl_line: String = in_str.to_string();
    loop {
        match EXPR_RE.is_match(&repl_line) {
            true => {
                for (_, [var_left, operand, var_right]) in
                    EXPR_RE.captures_iter(&repl_line).map(|c| c.extract())
                {
                    operands[i] = [var_left, var_right];
                    operators[i] = operand;
                    let orig_str = format!("({}{}{})", var_left, operand, var_right);
                    let repl_str = format!("[{}]", i);
                    repl_line = repl_line.replace(&orig_str, &repl_str);
                    i += 1;
                }
            }
            false => {
                break;
            }
        }
    }

    return (operators, operands);
}

问题是,在进行分配和替换的 内部,它不会让我分配,因为它是在 中借来的。我不知道如何绕过它或修复它。forrepl_lineEXPR_RE.captures_iter(&repl_line)

我知道一次传递有效,因为当我测试正则表达式并在不多次遍历字符串的情况下替换时,它可以正常工作并正确替换。代码如下所示:

fn _temp(in_str: &str) -> String {
    let mut operators: [&str; 64] = [""; 64];
    let mut operands: [[&str; 2]; 64] = [[""; 2]; 64];

    lazy_static! {
        static ref EXPR_RE: Regex =
            Regex::new(r"(\[?[A-Za-z0-9]+\]?)(==|&&|\|\||<=|!)(\[?[A-Za-z0-9]+\]?)").unwrap();
    }

    let mut i: usize = 0;
    let mut repl_line: String = in_str.to_string();
    for (_, [var_left, operand, var_right]) in EXPR_RE.captures_iter(in_str).map(|c| c.extract()) {
        operands[i] = [var_left, var_right];
        operators[i] = operand;
        let orig_str = format!("({}{}{})", var_left, operand, var_right);
        let repl_str = format!("[{}]", i);
        repl_line = repl_line.replace(&orig_str, &repl_str);
        i += 1;
    }

    return repl_line;
}

这已经正确完成了第一步,但我不知道如何使更完整的功能工作。任何帮助将不胜感激。rec_replace

rust 替换 borrow-checker

评论

0赞 Jmb 10/31/2023
请注意,您的工作代码不会就地发生更改。相反,它会创建一个带有替换项的新项,删除旧的,然后才将新的存储在 中。repl_lineStringStringStringrepl_line
0赞 Patrik Holub 10/31/2023
哦,我明白。因此,作为后续问题,我将使用什么来改变字符串。如果 replace() 不改变字符串,那会改变什么?
0赞 cafce25 10/31/2023
我希望有一个解决方案,replace_all使用 as 和 using 而不是 for both 和 .FnMutReplacerString&stroperatorsoperands
0赞 Patrik Holub 10/31/2023
我很抱歉关闭错误(),这是我的错。但是替换 => 是正确的。我不想要.而且我不明白你说我的正则表达式缺少一个封闭的文字是什么意思。正则表达式应该是什么样子吗?为什么我要捕获我正在执行的所有三个捕获?(a<=b)[0]([0])((some)(some)(some))
3赞 Chayim Friedman 10/31/2023
你真的应该把它解析成一个你可以轻松执行的适当的数据结构。

答: 暂无答案