我有一个服务方法,它接受一个String,然后用标签库中的项替换String中的标签。如下:
for( MetaDataDTO tag : tagValues )
{
message = message.replace( tag.getKey(), tag.getText1() );
}
显然;这使得大量的新字符串变得糟透了。但StringBuilder替换方法很难用于一个字符串中的多个字符串。如何使我的方法更有效率?
用于文本块,例如:
亲爱的#firstName#,#applicationType#的申请已被#approvedRejected#sorry。
其中#firstName#等是元数据数据库中的键。标签也可能不被散列字符包围。
答案 0 :(得分:9)
基本上你想复制Matcher.replaceAll()的执行,如:
public static String replaceTags(String message, Map<String, String> tags) {
Pattern p = Pattern.compile("#(\\w+)#");
Matcher m = p.matcher(message);
boolean result = m.find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
m.appendReplacement(sb, tags.containsKey(m.group(1) ? tags.get(m.group(1)) : "");
result = m.find();
} while (result);
m.appendTail(sb);
message = sb.toString();
}
return message;
}
注意:我对有效标记(即正则表达式中的\ w)做了一个假设。你需要为真正有效的东西提供这个(例如“#([\ w _] +)#”)。
我还假设上面的标签看起来像:
Map<String, String> tags = new HashMap<String, String>();
tags.add("firstName", "Skippy");
而不是:
tags.add("#firstName#", "Skippy");
如果第二个是正确的,你需要相应调整。
此方法只对消息字符串进行一次传递,因此它不会比这更有效。
答案 1 :(得分:0)
感谢您的帮助。当然更多地了解了java。这是我的解决方案。这种方式可以在标签中支持不同的标签和标签:
private static String replaceAllTags(String message, Map< String, String > tags)
{
StringBuilder sb = new StringBuilder( message );
boolean tagFound = false;
/**
* prevent endless circular text replacement loops
*/
long recurrancyChecker = 5000;
do
{
tagFound = false;
Iterator it = tags.entrySet().iterator();
while( it.hasNext() )
{
Map.Entry pairs = (Map.Entry) it.next();
int start = sb.indexOf( pairs.getKey().toString() );
while( start > -1 && --recurrancyChecker > 0 )
{
int length = pairs.getKey().toString().length();
sb.replace( start, start + length, pairs.getValue().toString() );
start = sb.indexOf( pairs.getKey().toString() );
tagFound = true;
}
}
}
while( tagFound && --recurrancyChecker > 0 );
return sb.toString();
}