Java转义HTML-字符串替换慢?

Java转义HTML-字符串替换慢?,java,Java,我有一个Java应用程序,它大量使用一个大文件来读取、处理并传递给SolrEmbeddedServer() 其中一个函数执行基本HTML转义: private String htmlEscape(String input) { return input.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;") .replace("'", "&apos;

我有一个Java应用程序,它大量使用一个大文件来读取、处理并传递给SolrEmbeddedServer()

其中一个函数执行基本HTML转义:

private String htmlEscape(String input)
{
    return input.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;")
        .replace("'", "&apos;").replaceAll("\"", "&quot;");
}
private String htmlEscape(字符串输入)
{

返回输入。replace(&),“&;”。replace(“>”,”)。replace()用于可以从中使用的html转义。它应该以一种更有效的方式实现。

这当然不是进行大量替换的最有效方式。由于字符串是不可变的,因此每个.replace()导致构造一个新的字符串对象。对于您给出的示例,每次调用此函数都会导致临时创建6个字符串对象

考虑到您给出的示例,最简单的解决方案是使用现有的库函数进行HTML实体编码。Apache commons是一个选项。另一个选项是

在其类中有一个非常有效的方法

它相当聪明,不使用您描述的字符串替换方式,而是遍历字符,在找到字符时用适当的实体替换字符


我手头没有任何基准测试,但是如果这些东西在您的代码的关键路径上,您将很乐意使用这个现成的、更快的解决方案。

您使用多个替换方法的方法可能会很慢


查看s以获得转义HTML实体的快速实现。

字符串.replace的通用算法有点复杂,但不应该那么糟糕。查看代码,它实际上是使用正则表达式实现的,因此不会很快

显然,通过逐字符迭代,您可以编写速度更快的代码。可能需要先计算出确切的长度


您可能想考虑<代码> [-~]之外的字符如何

已处理。您可能还希望使用已实现该功能的库。

每次调用replace都会返回一个新字符串。每次调用此函数时,您实际上是在创建字符串的四个副本,这些副本将被立即丢弃。如果输入足够大,这可能是浪费

我建议修改您的算法,以便您只扫描列表一次,而不是执行N
replace
操作(每次都需要扫描字符串):

//psuedocode
Map<Char, String> replacements = new HashMap<String, String>();
replacements.put("&", "&amp;");
replacements.put(">", "&gt;");
...
private String htmlEscape(String input) {
    StringBuilder sb = new StringBuilder(input.length());
    for (char c: sb.toCharArray()) {
    if (replacements.containsKey(c)) {
        sb.append(replacements.get(c));
    else {
        sb.append(c);
    }
    return sb.toString();
}
//伪代码
Map replacements=newhashmap();
替换。将(“&”、“&;”号填上;
替换。放置(“>”,“);
...
私有字符串htmlEscape(字符串输入){
StringBuilder sb=新的StringBuilder(input.length());
for(char c:sb.toCharArray()){
if(替代品。集装箱(c)){
sb.append(replacements.get(c));
否则{
sb.附加(c);
}
使某人返回字符串();
}

使用起来更简单、更标准。非常简单。

对于普通读者,Html转义字段中有一个新的播放器:

HTML代码上的unescape操作可以如下所示:

final String unescapedText = HtmlEscape.unescapeHtml(escapedText); 

我建议从commons lang复制这个方法(因为它是ASF2.0许可的,所以您可以合法地这么做)除非您需要commons-lang提供的任何其他方法和帮助器类。对单个方法有一个全新的依赖关系是不好的。是的,但是commons-lang有太多的方法,可能在大多数应用程序中都很有用,它们的作者在不知道它们存在的情况下重新编写了它们。谢谢,这可能会很有用。如果我没有错的话总而言之,该项目已经使用apache commons作为Solr的依赖项。我将对此进行研究:)我已经更改了我的实现,以检查字符串中是否有某个字符,希望if比直接执行更快…(目前还没有结果,但我可能会按照其他人的建议使用StringEscapeUtils)