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

发布于 2024-07-18 21:22:10 字数 417 浏览 4 评论 0原文

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

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

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

它用于文本块,例如:

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

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

I have a service method that takes a String and then replaces tags in the String with items from a tag library. As follows:

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

Obviously; this make heaps of new strings and is BAD. But the StringBuilder replace method is cumbersome to use for multiple strings inside one string. How can I make my method more efficient?

It is for use with blocks of text such as:

Dear #firstName#, your application for #applicationType# has been #approvedRejected# sorry.

Where #firstName#, etc are the keys in a meta data database. It is also possible that tags may not be surrounded by hash characters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江心雾 2024-07-25 21:22: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");

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

此方法只对消息字符串进行一次传递,因此没有比这更高效的方法了。

Basically you want to copy the execution of Matcher.replaceAll() like so:

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

Note: I've made an assumption about the valid tag (namely \w in the regex). You will need to cater this for what's really valid (eg "#([\w_]+)#").

I've also assumed the tags above looks something like:

Map<String, String> tags = new HashMap<String, String>();
tags.add("firstName", "Skippy");

and not:

tags.add("#firstName#", "Skippy");

If the second is correct you'll need to adjust accordingly.

This method makes exactly one pass across the message string so it doesn't get much more efficient than this.

只是一片海 2024-07-25 21:22:10

库中的解决方案:“org.apache.commons:commons-text:{version}”。

使用示例:

import org.apache.commons.text.StringSubstitutor;

public class Main {
    public static void main(String[] args) {
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("name", "World!");
        String expectedResult = "Hello, World!";

        // default - prefix: "${", suffix: "}"
        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));
    }
}

Solution from library: 'org.apache.commons:commons-text:{version}'.

Usage example:

import org.apache.commons.text.StringSubstitutor;

public class Main {
    public static void main(String[] args) {
        Map<String, String> valuesMap = new HashMap<>();
        valuesMap.put("name", "World!");
        String expectedResult = "Hello, World!";

        // default - prefix: "${", suffix: "}"
        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));
    }
}
年华零落成诗 2024-07-25 21:22:10

谢谢你们的帮助。 当然了解了更多关于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();
}

Thanks for your help guys. Certainly learned more about java. Here is my solution. It is this way to support different looking tags and tags within tags:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文