string - 用 JRE 库替换 StrSubstitutor

标签 string text java

目前我正在使用 org.apache.commons.lang.text.StrSubstitutor 来做:

Map m = ...
substitutor = new StrSubstitutor(m);

result = substitutor.replace(input);

鉴于我想从我的项目中删除 commons-lang 依赖项,使用标准 JRE 库的 StrSubstitutor 的工作和简约实现是什么?

注意:

StrSubstitutor 是这样工作的:

Map map = new HashMap();
map.put("animal", "quick brown fox");
map.put("target", "lazy dog");
StrSubstitutor sub = new StrSubstitutor(map);
String resolvedString = sub.replace("The ${animal} jumped over the ${target}.");

yielding resolvedString = "敏捷的棕色狐狸跳过了懒狗。"

最佳答案

如果性能不是优先事项,您可以使用 appendReplacement method of the Matcher class :

public class StrSubstitutor {
    private Map<String, String> map;
    private static final Pattern p = Pattern.compile("\\$\\{(.+?)\\}");

    public StrSubstitutor(Map<String, String> map) {
        this.map = map;
    }

    public String replace(String str) {
        Matcher m = p.matcher(str);
        StringBuilder sb = new StringBuilder();
        while (m.find()) {
            String var = m.group(1);
            String replacement = map.get(var);
            m.appendReplacement(sb, replacement);
        }
        m.appendTail(sb);
        return sb.toString();
    }
}

性能更高但更丑陋的版本,只是为了好玩:)

    public String replace(String str) {
        StringBuilder sb = new StringBuilder();
        char[] strArray = str.toCharArray();
        int i = 0;
        while (i < strArray.length - 1) {
            if (strArray[i] == '$' && strArray[i + 1] == '{') {
                i = i + 2;
                int begin = i;
                while (strArray[i] != '}') ++i;
                sb.append(map.get(str.substring(begin, i++)));
            } else {
                sb.append(strArray[i]);
                ++i;
            }
        }
        if (i < strArray.length) sb.append(strArray[i]);
        return sb.toString();
    }

根据我的测试,它比 regex 版本快 2 倍,比 apache commons 版本快 3 倍。所以普通的正则表达式实际上比 apache 版本更优化。通常当然不值得。只是为了好玩,让我知道您是否可以对其进行更优化。

编辑:正如@kmek 指出的那样,有一个警告。 Apache 版本将传递解析。例如,如果 ${animal} 映射到 ${dog} 并且 dog 映射到 Golden Retriever,apache 版本将 ${animal} 映射到 Golden Retriever。正如我所说,您应该尽可能地使用库。上述解决方案仅在您有不允许您使用库的特殊约束时使用。

关于string - 用 JRE 库替换 StrSubstitutor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14044715/

相关文章:

Java 数组、实例化和排序

c++ - 字符串类实现的差异

c++ - 带 NULL 的 Strtok 用法

php - 无法将 MySQL 表转储分解为与表行对应的新行

javascript - Cufon...简单的渐变文本...不起作用

PHP mysql格式化文本

string - VBA - 转换为日期

c++ - 不复制的char */字符串连接?

java - 简单的Java并发问题

java - 内联实例类作为枚举中的参数