лучший способ заменить все теги в строке с Java - PullRequest
1 голос
/ 03 мая 2009

У меня есть служебный метод, который принимает строку, а затем заменяет теги в строке на элементы из библиотеки тегов. Следующим образом:

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

Очевидно, это делает кучу новых строк и плохо. Но метод замены StringBuilder неудобен в использовании для нескольких строк внутри одной строки. Как я могу сделать мой метод более эффективным?

Используется с блоками текста, такими как:

Уважаемый # firstName #, ваша заявка на # applicationType # была # утвержденаОтклонено # извините.

Где # firstName # и т. Д. - ключи в базе метаданных. Также возможно, что теги не могут быть окружены хеш-символами.

Ответы [ 2 ]

9 голосов
/ 03 мая 2009

В основном вы хотите скопировать выполнение 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 голосов
/ 06 мая 2009

Спасибо за вашу помощь, ребята. Конечно, узнал больше о 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();
}
...