regex - 如何使用 RegexSet 执行替换?
问题描述
给定一个配置文件,它指定了几个(可能几十个)正则表达式,例如:
("2018")
authors[ ]*=[ ]*(.*)
我想遍历输入流(逐行)并替换所有捕获(在此示例中,“2018”的所有实例和作者姓名)。替换取决于捕获,因此年份将替换为“(年份)”,作者姓名替换为“(作者)”。
我试过的
extern crate regex; // 1.1.5
use regex::Regex;
use regex::RegexSet;
use std::process;
use std::{
fs::File,
io,
io::{prelude::*, BufReader},
path::PathBuf,
};
fn main() {
let contents = read_to_array("config.conf");
println!("{:?}", contents);
let set = RegexSet::new(&contents).unwrap(); // FIXME: this panics if there is an invalid regex
println!("{:?}", set);
let mut regexs: Vec<Regex> = Vec::new();
for line in contents {
let re = Regex::new(&line).unwrap(); // should not panic because we parsed Regexes above already
regexs.push(re);
}
read(set, regexs);
}
fn read_to_array(filename: &str) -> Vec<String> {
let file = File::open(filename).expect("no such file");
let buf = BufReader::new(file);
buf.lines()
.map(|l| l.expect("Could not parse line"))
.collect()
}
fn read(set: RegexSet, regexs: Vec<Regex>) {
let stdin = io::stdin();
for line in stdin.lock().lines() {
let l = line.unwrap();
let mut r = l.to_string();
println!("line: {}", l);
for idx in set.matches(&l).into_iter() {
println!(
"matches: {:?} - {:?} = {:?}",
idx,
set.patterns()[idx],
regexs[idx]
);
for caps in regexs[idx].captures_iter(&l) {
println!("captures: {:?}", caps);
for c in caps.iter() {
println!("cap: {:?}", c);
}
r = regexs[idx].replace_all(&r, "xxx").to_string();
println!("result: {:?}", r);
}
}
println!("new line: {}", r);
}
}
这需要regex = "1"
在 Cargo.toml 中,需要在config.conf
当前目录中命名的配置文件,以及通过标准输入管道输入的数据 - Cargo.toml 可以很好地用于测试目的。
什么不起作用
RegexSet
没有给我捕获,所以我用它来有效地确定我是否有匹配,然后再次匹配以进行替换。这让我觉得非常笨重,但这是我让它工作的唯一方法。
其次,替换总是替换整个匹配,而不仅仅是捕获的部分。那是我不明白的事情,它不适合正则表达式箱的文档。
第三,遍历捕获 - 这可能是#2的原因 - 总是给我索引0处的整个匹配,我想跳过它。Rust 中是否有类似“迭代这个,但跳过第一个元素”的东西?
解决方案
推荐阅读
- git - 从文件中删除所有未跟踪
- html - CSS 正确:-50 并且过渡不起作用
- java - JavaFX 2 秒后在 GridPane 上添加行
- python - 错误:ImportError: cannot import name 'doSum' from 'Sum' (G:\firstpy\Sum.py)
- javascript - 意外的令牌 = import/no-named-as-default eslint 错误
- shell - 使用shell脚本awk将另一个字段上的函数结果附加到csv中
- python - 如何在 keras 神经网络中进行简单的数据召回
- java - LazyCsrfTokenRepository$SaveOnAccessCsrfToken 无法转换为 CsrfToken
- flutter - 底部溢出 30px
- game-maker - Gamemaker Studio 2 中的弹丸不动