如何遍历字符串并替换某些短语?

时间:2016-01-05 13:30:53

标签: regex rust

我希望能够将“你是”等短语替换为“我是”,将“你的”替换为“我的”。如何在保持代码DRY的同时执行此操作?

到目前为止,我有类似的东西......

let re = Regex::new(r"you are").unwrap();
re.replace_all("you are awesome and so is your hat", "I am")

但这只取代了“你是”而不是“我的”部分。

我认为理想情况下它看起来像

let re = Regex::new(r"your|you are").unwrap();
re.replace_all("you are awesome and so is your hat", fn_with_pattern_matching)

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

let str = "you are awesome and so is your hat";
let re = Regex::new(r"you are").unwrap();
let re1 = Regex::new(r"your").unwrap();
re.replace_all(str, "I am");
re1.replace_all(str, "my");

修改:

如果要更换很多短语,请创建("要替换的短语","要用&#34替换的短语;)并迭代它以执行上述逻辑。

答案 1 :(得分:1)

让我们从karthik manchala回答和Shepmaster建议开始:

  

将所有字符串放在一个数组中并迭代数组。如果你的   应用逻辑是“用B替换所有A,然后用D替换所有C”   所有E与F“,然后代码将反映重复的逻辑。

我不建议将字符串保存在数组中,而是建议将编译好的正则表达式存储在那里,以免每次都重建它们。

以下是代码:

extern crate regex;

use regex::Regex;
use std::env::args;
use std::iter::FromIterator;

fn main() {
    let patterns = [("your", "mine"), ("you are", "I am")];
    let patterns = Vec::from_iter(patterns.into_iter().map(|&(k, v)| {
        (Regex::new(k).expect(&format!("Can't compile the regular expression: {}", k)),
         v)
    }));
    for arg in args().skip(1) {
        println!("Argument: {}", arg);
        for &(ref re, replacement) in patterns.iter() {
            let got = re.replace_all(&arg, replacement);
            if got != arg {
                println!("Changed to: {}", got);
                continue;
            }
        }
    }
}

就是这样,但为了完整起见,我想补充一点,如果你想获得更好的性能,那么你可以使用MARK正则表达式引擎中存在的PCRE功能({ {3}} crate)。

使用MARK和类似的模式

"(?x) ^ (?:
    (*MARK:0) first pattern \
  | (*MARK:1) second pattern \
  | (*MARK:2) third pattern \
)"

您可以使用MARK数字进行分类,或者在您的情况下,将其作为具有替换的数组的索引。这通常比使用多个正则表达式更好,因为主题字符串只处理一次。