有没有其他方法可以更有效地使用尽可能少的内存来更有效地执行“replaceAll”呢?
public static String cleanWordTags(String source) {
String copy = source;
copy = copy.replaceAll("<P style=\"M[^>]*>", "<P>");
copy = copy.replaceAll("<p style=\"M[^>]*>", "<p>");
copy = copy.replaceAll("<p style=\"T[^>]*>", "<p>");
copy = copy.replaceAll("<b style=[^>]*>", "<b>");
copy = copy.replaceAll("<span class=\"M[^>]*>", "<span>");
copy = copy.replaceAll("<span style='m[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"f[^>]*>", "<span>");
copy = copy.replaceAll("<span lang[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"color[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"m[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"line[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"L[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"T[^>]*>", "<span>");
copy = copy.replaceAll("<span style=\"t[^>]*>", "<span>");
copy = copy.replaceAll("<br [^>]*>", "<br/>");
copy = copy.replaceAll("<i style=[^>]*>", "");
copy = copy.replaceAll("</i>", "");
copy = copy.replaceAll("<st1:personname[^>]*>", "");
copy = copy.replaceAll("</st1:personname>", "");
copy = copy.replaceAll("<st1:metricconverter[^>]*>", "");
copy = copy.replaceAll("</st1:metricconverter>", "");
copy = copy.replaceAll("<br[^>]*>", "<br/>");
copy = copy.replaceAll("<\\W\\Wendif\\W\\W\\W>", "");
copy = copy.replaceAll("<![^>]*>", "");
copy = copy.replaceAll("<[vowm]:[^>]*>", "");
copy = copy.replaceAll("</[vowm]:[^>]*>", ""); //&
copy = copy.replaceAll("&(amp|lt|gt);", "");
copy = copy.replaceAll(" ", "");
copy = copy.replaceAll("<img width[^>]*>", "");
copy = copy.replaceAll("<img src=\"file:[^>]*>", "");
return copy;
}
我发现我可以使用StringUtils.replace而不是replaceAll,但这只适用于没有正则表达式的字符串。
谢谢!
新的:
我尝试使用与注释相关的下一段代码,但替换相同的字符串需要花费5倍的时间:
public static String cleanWordTags(String source) {
String copy = source;
long t0 = System.currentTimeMillis();
String regex = "";
regex += "(align=\"left\")";
regex += "|(<mce:style>)";
regex += "|(<i>)";
regex += "|(<i style=[^>]*>)";
regex += "|(</i>)";
regex += "|(<st1:personname[^>]*>)";
regex += "|(</st1:personname>)";
regex += "|(<st1:metricconverter[^>]*>)";
regex += "|(</st1:metricconverter>)";
regex += "|(<\\W\\Wendif\\W\\W\\W>)";
regex += "|(<![^>]*>)";
regex += "|(<[vowm]:[^>]*>)";
regex += "|(</[vowm]:[^>]*>)";
regex += "|(&(amp|lt|gt);)";
regex += "|( )";
regex += "|(<img width[^>]*>)";
regex += "|(<img src=\"file:[^>]*>)";
Pattern p = Pattern.compile(regex);
copy = p.matcher(copy.toUpperCase()).replaceAll("");
regex = "";
regex += "(<span style=\"t[^>]*>)";
regex += "|(<span style=\"T[^>]*>)";
regex += "|(<span style=\"L[^>]*>)";
regex += "|(<span style=\"line[^>]*>)";
regex += "|(<span style=\"m[^>]*>)";
regex += "|(<span style=\"color[^>]*>)";
regex += "|(<span lang[^>]*>)";
regex += "|(<span style=\"f[^>]*>)";
regex += "|(<span style='m[^>]*>)";
regex += "|(<span class=\"M[^>]*>)";
p = Pattern.compile(regex);
copy = p.matcher(copy.toUpperCase()).replaceAll("");
copy = copy.replaceAll("<br[^>]*>", "<br/>");
//Sustituir
// copy = copy.replaceAll("<p class=[^>]*>", "<p>");
// copy = copy.replaceAll("<p align=[^>]*>", "<p>");
copy = copy.replaceAll("<P style=\"M[^>]*>", "<P>");
copy = copy.replaceAll("<p style=\"M[^>]*>", "<p>");
copy = copy.replaceAll("<p style=\"T[^>]*>", "<p>");
copy = copy.replaceAll("<b style=[^>]*>", "<b>");
System.out.println(System.currentTimeMillis() - t0);
return copy;
}
发布于 2014-10-17 04:32:13
最后,我找到的唯一解决方案是将所有没有regex的"replaceAll“替换为”替换“,并尝试泛化正则表达式。
非常感谢!
发布于 2014-10-15 03:46:09
您是否已经看过流传单(参见:https://code.google.com/p/streamflyer/),尽管我不能说明性能方面的任何内容,但它们声明:“修改流中的字符--应用正则表达式,修复XML文档,无论您想做什么。”
此外还有streamflyer-regex-fast (参见:https://code.google.com/p/streamflyer-regex-fast/),它“提供了一个比streamflyer使用的算法更快的算法来匹配字符流上的正则表达式”。
因此,如果您的数据可用为Reader
,例如StringReader
,您可以很容易地将该示例从首页应用到代码中,如下所示:
Reader reader = new StringReader("source <p style=\"Memphis\">");
FastRegexModifier modifier = new FastRegexModifier("<P style=\"M[^>]*>", Pattern.CASE_INSENSITIVE, "<P>");
ModifyingReader modifyingReader = new ModifyingReader(reader, modifier);
String result = IOUtils.toString(modifyingReader);
这具有可以使用CASE_INSENSITIVE
标志的优点,这可能减少了需要定义的规则的数量。但请注意:这也可能影响性能,因此您应该评估这两种可能性。
如果此解决方案有助于提高您的性能,请报告。
发布于 2014-10-15 05:03:11
即使您想使用regexes,这种方式也是非常低效率的,因为您一次又一次地搜索整个字符串(并创建大量垃圾)。正确的方法是在类似于Matcher
的循环中使用这一个进行迭代。
只要让你匹配所有可能感兴趣的东西,并分支于它所发现的。你的模式可能是
(?:<(p|b|span|br|i|st1:personname|st1:metricconverter|\\W\\Wendif\\W\\W\\W|!|vowm:|img))[^>]+>)|&(amp|lt|gt|nbsp);
它比您想要的更匹配,但在这种情况下可以将替换设置为$0
。它只需要一次穿过整个字符串。你可能想做两次传球,而不是保持简单。
https://stackoverflow.com/questions/26380982
复制相似问题