用java替换字符串中所有标签的最佳方法

问题描述 投票:0回答:3

我有一个服务方法,它接受一个字符串,然后用标签库中的项目替换字符串中的标签。如下:

for( MetaDataDTO tag : tagValues )
{
    message = message.replace( tag.getKey(), tag.getText1() );
}

显然;这会产生大量新字符串,这是不好的。但是 StringBuilder 的替换方法对于一个字符串中的多个字符串使用起来很麻烦。我怎样才能让我的方法更有效?

它适用于文本块,例如:

亲爱的#firstName#,您的#applicationType#申请已被#approvedRejected#抱歉。

其中#firstName#等是元数据数据库中的键。标签也可能没有被哈希字符包围。

java string replace stringbuilder
3个回答
10
投票

基本上你想复制 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");

如果第二个正确,您需要进行相应调整。

此方法只对消息字符串进行一次传递,因此它不会比这更高效。


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();
}

0
投票

来自库的解决方案:'org.apache.commons:commons-text:{version}'。

使用示例:

import org.apache.commons.text.StringSubstitutor;

public class Main {
    public static void main(String[] args) {
        // default - prefix: "${", suffix: "}"
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("name", "World!");
        String expectedResult = "Hello, World!";

        String source1 = "Hello, ${name}";
        StringSubstitutor sub1 = new StringSubstitutor(valuesMap);
        String result1 = sub1.replace(source1);
        System.out.println(expectedResult.equals(result1));

        // custom - prefix: "{{", suffix: "}}"
        String source2 = "Hello, {{name}}";
        StringSubstitutor sub2 = new StringSubstitutor(valuesMap, "{{", "}}");
        String result2 = sub2.replace(source2);
        System.out.println(expectedResult.equals(result2));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.