パフォーマンスが優先されない場合は、クラスのappendReplacement
メソッドをMatcher
使用できます。
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();
}
テストによると、正規表現バージョンの約 2 倍、Apache Commons バージョンの約 3 倍高速です。したがって、通常の正規表現は実際には apache バージョンよりも最適化されています。もちろん、通常はそれだけの価値はありません。楽しみのために、もっと最適化できるかどうか教えてください。
編集: @kmek が指摘しているように、注意点があります。Apache のバージョンは推移的に解決されます。たとえば、および に${animal}
マップする場合、apache バージョンはGolden Retriever にマップされます。私が言ったように、可能な限りライブラリを使用する必要があります。上記の解決策は、ライブラリの使用を許可しない特別な制約がある場合にのみ使用してください。${dog}
dog
Golden Retriever
${animal}