4

私は現在、特定の文字列を複数の変数に置き換える構成ファイルを作成しています。説明するのに苦労しているので、おそらく私が何を意味するのかを示すのが最善でしょう:

次のメソッドが文字列で使用されます: Hello ~ and Welcome to ~!

private static String REPLACE_CHAR = "~";

public static String parse(String key, String... inputs) {
    int cache = matchCache.get(key, -1);
    String value = customConfig.getString(key);
    if (cache == -1) {
        cache = StringUtils.countMatches(value, REPLACE_CHAR);
        matchCache.put(key, cache);
    }
    for (int i = 0; i < cache; i++) {
        value = value.replaceFirst(REPLACE_CHAR, inputs[i]);
    }
    return value;
}

~ を最初の入力に置き換えてから、2 番目の ~ に移動する最速の方法は何でしょう...

今、私が他の誰かのコードを使用していない主な理由: 理想的には、変数を自動的に置き換えるさまざまな置換可能な文字のリストを作成したいので、この同じコードでは入力を与えることができませんが、置換可能な文字のリストをチェックし、getYourName() などのメソッドを実行します。このリストは毎回チェックする必要がないので、パターンはコンパイルされますか?

私は効率と同じくらい学ぶためにこれをやっています.正規表現に関しては私には能力がありません!

4

1 に答える 1

2

効率を求めている場合はMatcher、正規表現を使用して をインスタンス化し、find()メソッドを使用して出現箇所を検索し、各出現箇所の置換を に追加しますStringBuffer

private Matcher matcher = Pattern.compile("([~])").matcher("");

public String parse(String key, String... inputs) {
    String value = customConfig.getString(key);
    matcher.reset(value);
    StringBuffer sb = new StringBuffer();
    int i = 0;
    while (matcher.find()) {
      String text = matcher.group(1);
      matcher.appendReplacement(sb, inputs[i++]);
    }
    matcher.appendTail(sb);
    return sb.toString();
}

System.out.println(parse("foo", "T F C", "James Bond"));
// prints "Hello T F C, my name is James Bond" 
// if customConfig.getString("foo") returns "Hello ~, my name is ~"

このようにして、に含まれる各ループ中に文字列の先頭からの検索を回避しますString.replaceFirst。ただし、 の長さがそれに等しいこと~を確認したい場合は、見つかった数をキャッシュすることができます。input[]

上記のサンプルは、正しい数のエントリが に格納されているという事実を無視していますinputs[]

実行可能なサンプルはこちらにあります: http://ideone.com/QfE03a

于 2012-11-12T22:28:13.860 に答える