2

String を受け取り、String 内のタグをタグ ライブラリのアイテムに置き換えるサービス メソッドがあります。次のように:

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

明らかに; これは新しい文字列のヒープを作成し、悪いことです。しかし、StringBuilder の replace メソッドは、1 つの文字列内の複数の文字列に対して使用するのは面倒です。メソッドをより効率的にするにはどうすればよいですか?

次のようなテキスト ブロックで使用します。

親愛なる #firstName# 様、#applicationType# へのあなたの申請は #approvedRejected# でした。申し訳ありません。

#firstName# などは、メタ データ データベースのキーです。タグがハッシュ文字で囲まれていない可能性もあります。

4

2 に答える 2

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");

2 番目が正しい場合は、それに応じて調整する必要があります。

このメソッドは、メッセージ文字列全体で 1 回だけパスを作成するため、これよりもはるかに効率的ではありません。

于 2009-05-03T10:25:44.040 に答える
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();
}
于 2009-05-06T02:38:42.030 に答える