如何遍历字符串并替换某些短语?
Posted
技术标签:
【中文标题】如何遍历字符串并替换某些短语?【英文标题】:How do I iterate through a string and replace certain phrases? 【发布时间】:2016-01-05 13:30:53 【问题描述】:我希望能够将诸如“you are”替换为“I am”以及将“your”替换为“my”之类的短语。如何在保持代码 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)
【问题讨论】:
写两个单独的 replace_all 语句怎么样? 你最后一次使用fn_with_pattern_matching
的sn-p 应该是可行的。请参阅 regex
文档中的示例:doc.rust-lang.org/regex/regex/enum.Regex.html#examples-2 不过,您可能需要使用捕获组来确定要使用哪个文本作为替换。
@BurntSushi5,是的,我尝试过使用捕获组,但我在理解文档时遇到了很多麻烦,似乎无法让它按预期工作
@BurntSushi5 我认为该方法还需要我明确识别捕获索引号,如果我不知道字符串是否包含这些短语,这是不可取的
请edit你的问题表明你已经尝试过。 Stack Overflow 不是其他人为您编写代码的服务。向我们展示您为实现 fn_with_pattern_matching
而编写的内容,我们可以帮助实现这一目标。
【参考方案1】:
让我们从karthik manchala
回答和Shepmaster
建议开始:
将所有字符串放在一个数组中并遍历该数组。如果你的 应用程序逻辑是“将所有 A 替换为 B,然后将所有 C 替换为 D,然后 所有 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;
就是这样,但为了完整起见,我想补充一点,如果您想要卓越的性能,那么您可以使用 PCRE
正则表达式引擎 (pcre crate) 中的 MARK
功能.
MARK
和这样的模式
"(?x) ^ (?:
(*MARK:0) first pattern \
| (*MARK:1) second pattern \
| (*MARK:2) third pattern \
)"
您可以使用MARK
编号进行分类,或者在您的情况下作为带有替换的数组的索引。这通常比使用多个正则表达式更好,因为主题字符串只处理一次。
【讨论】:
“因为主题字符串只被处理一次”——这也改变了行为,对吗?例如,如果我替换A -> BC
和 B -> XY
,那么创建多个循环与具有多个匹配项的单个循环将产生不同的结果。
@Shepmaster 这首先取决于循环是如何实现的以及正则表达式是什么。在某些情况下,行为是相同的,唯一的区别在于运行时成本。像往常一样,开发人员应该了解她在做什么。我在这里的目标不是写一本关于正则表达式MARK
及其所有细微差别的书,而是简单地提及这个有价值的工具。 ; )【参考方案2】:
您可以执行以下操作:
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");
编辑:
如果您有很多短语要替换,请创建一个 ("phrase to replace", "phrase to replace with") 的映射并对其进行迭代以执行上述逻辑。
【讨论】:
感谢您的建议,但这不是很干燥,而且根本不能很好地扩展。我打算添加更多的短语来替换(例如“我”到“你”......等等) 但这不是很干 - 将所有字符串放在一个数组中并遍历该数组。如果您的应用程序逻辑是“将所有 A 替换为 B,然后将所有 C 替换为 D,然后将所有 E 替换为 F”,那么代码将反映该重复逻辑。以上是关于如何遍历字符串并替换某些短语?的主要内容,如果未能解决你的问题,请参考以下文章