如何使用正则表达式捕获组中的格式化字符串执行替换?

时间:2019-09-09 16:48:00

标签: regex rust

我正在使用regex板条箱一次进行多次替换:

cat file.csv | grep -v $variable

预期输出:

extern crate regex;

use regex::{Captures, Regex};

fn transform(string: &str) {
    let rgx = Regex::new(r"(\n)|(/\w+)").unwrap();
    let res = rgx.replace_all(string, |caps: &Captures| {
        if caps.get(1).is_some() {
            return " ";
        }
        match caps.get(2).map(|m: regex::Match| m.as_str()) {
            Some(z) => return "nope", // how to return formatted z instead?
            None => (),
        }
        unreachable!();
    });
    println!("{}", res);
}

fn main() {
    transform("no errors");
    transform("big\nbad\n/string");
}

我想返回no errors big bad nope 而不是以某种方式格式化。由于z /生存期问题,format!似乎无法在此处使用:

String
match caps.get(2).map(|m: regex::Match| m.as_str()) {
    Some(z) => return format!("cmd: {}", z),
    None => (),
}

应该怎么做?

1 个答案:

答案 0 :(得分:1)

在错误消息中注意:

  

预期&str

它需要一个&str,因为这是闭包返回的第一个类型:

return " ";

闭包/函数只能有一种返回类型,不能有两种。

最简单的解决方法是在两种情况下都返回String

let res = rgx.replace_all(string, |caps: &Captures| {
    if caps.get(1).is_some() {
        return String::from(" ");
    }
    let m = caps.get(2).unwrap();
    format!("cmd: {}", m.as_str())
});

要稍微提高效率,可以避免为空格字符分配String

use std::borrow::Cow;
let res = rgx.replace_all(string, |caps: &Captures| {
    if caps.get(1).is_some() {
        return Cow::from(" ");
    }
    let m = caps.get(2).unwrap();
    Cow::from(format!("cmd: {}", m.as_str()))
});

playground

我还用match臂代替了=> (),而将unreachable!和较短的unwrap配对。

另请参阅: