在字符串中替换多个单词的最有效方法

32

目前我正在进行以下事项

示例:

line.replaceAll(",","").replaceAll("cat","dog").replaceAll("football","rugby");

我认为它很丑陋。不确定有更好的方法吗?也许可以通过哈希表进行循环遍历吗?

编辑:

通过效率我指的是更好的代码风格和灵活性。


4
你的问题是关于运行效率吗?灵活性?代码风格?请澄清。 - Mac
2
这也可能是正确性的问题,因为在进行N次替换时所做的替换可能不等同于在单次替换中执行N对替换。 - Xion
2
已更新问题,但寻求更好的代码样式并允许灵活性。 - Decrypter
2
类似问题:https://dev59.com/JnM_5IYBdhLWcg3wjj-r - Kip
4个回答

23

这个功能已经在Commons LangStringUtils类中实现了。

StringUtils.replaceEach(String text, String[] searchList, String[] replacementList)

1
我相信它不在标准库中,而是在Apache Commons中链接 - tkokasih
新版本将是来自Apache Commons TextStrSubstitutor - Andreas
1
StrSubstitutor似乎具有不同于标准替换的目的。 - Christopher Schneider

22

您可以使用Matcher.appendReplacement()/appendTail()构建非常灵活的搜索和替换功能。

JavaDoc中的示例如下:

Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat two cats in the yard");
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, "dog");
}
m.appendTail(sb);
System.out.println(sb.toString());

现在,在那个while循环中,您可以自行决定替换文本并基于实际匹配的内容进行信息。

例如,您可以使用模式 (,|cat|football) 来匹配 ,cat football ,并根据循环内的实际匹配结果决定实际替换。

您可以通过这种方式构建更加灵活的东西,比如将所有十进制数替换为十六进制数或进行类似操作。

虽然这不像您的代码那样 简短简单,但是您可以使用它构建简短而简单的方法。


如果你有数百个不同的单词需要检查怎么办?每个单词都必须扫描整个字符串,这非常低效。 - Jack Cole
@JackCole:不,你不会这样做。请检查一下讨论多个单词模式的段落。你仍然可以构建一个包含任意数量单词的单一模式。 - Joachim Sauer
啊,我现在明白了。你可以跟进一个 Map 查询那个单词。我想知道这与上面的答案相比表现如何。 - Jack Cole
例如,您可以使用模式(,|cat|football)来匹配“,”、“cat”或“football”,并根据循环内的实际匹配决定实际替换。你是说我可以在一个while循环中用'.'替换',',用'dog'替换'cat'吗?这看起来怎么样? - Blaisem
@Blaisem:没错,这就是你可以做的。在 while 循环内部,只需检查 m.group() 的返回值并根据返回的内容使用不同的第二个参数调用 appendReplacement - Joachim Sauer

4
除此之外,实际的替换被内部转换为一个regex,我认为这种方法很好。非正则表达式的实现可以在StringUtils.replace(..)中找到。
看看可能有哪些替代方案,你仍然需要找到一些用于识别字符串对的东西。这可能看起来像:
MultiReplaceUtil.replaceAll{line, 
       {",", ""}, {"cat", "dog"}, {"football", "rugby"}};

或者说,可能
MapReplaceUtil(String s, Map<String, String> replacementMap);

或者甚至更多。
ArrayReplaceUtil(String s, String[] target, String[] replacement);

对我来说,无论从编码实践的角度来看,两者都不太直观。


2

对于Scala的爱好者:

"cat".r.replaceAllIn("one cat two cats in the yard", m => "dog")

使用m,您甚至可以对替换参数化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接