2013-06-27 10 views
5

書式付きの「プロパティ」を含む文字列が与えられます。Java文字列内の書式付きプロパティの検索と置換

"これは私が$ {given}になるかもしれない$ {string}の$ {example}です"という文字列が標準の "$ {"と "}"トークンの内部にカプセル化されています。

私はまた、それぞれの可能なフォーマットされたプロパティのHashMap<String,String>含む置換を持つことになります。

HashMap Keys   HashMapValues 
=========================================== 
bacon     eggs 
ham     salads 

だから、以下の文字列与えられた:「私は$ {ベーコンを}食べるのが好き

をと$ {ハム}。

私はに変換しますJavaメソッドにこれを送信することができます。

「私は卵とサラダを食べるのが好き。」ここで

私の最高の試みだ:私はこれを実行すると

System.out.println("Starting..."); 

String regex = "$\\{*\\}"; 
Map<String,String> map = new HashMap<String, String>(); 
map.put("bacon", "eggs"); 
map.put("ham", "salads"); 

String sampleString = "I like ${bacon} and ${ham}."; 

Pattern pattern = Pattern.compile(regex); 
Matcher matcher = pattern.matcher(sampleString); 
while(matcher.find()) { 
    System.out.println("Found " + matcher.group()); 

    // Strip leading "${" and trailing "}" off. 
    String property = matcher.group(); 

    if(property.startsWith("${")) 
     property = property.substring(2); 
    if(property.endsWith("}")) 
     property = property.substring(0, property.length() - 1); 

    System.out.println("Before being replaced, property is: " + property); 

    if(map.containsKey(property)) 
     property = map.get(property); 

    // Now, not sure how to locate the original property ("${bacon}", etc.) 
    // inside the sampleString so that I can replace "${bacon}" with 
    // "eggs". 
} 

System.out.println("Ending..."); 

、私はエラーを取得していないが、ちょうど「開始...」と「エンディング...」の出力を参照してください。これは私の正規表現が間違っていることを示しているので、Matcherはどのプロパティとも一致することができません。

私の最初の質問は:この正規表現は何でしょうか?

これを過ぎると、「$ {ベーコン}」を「卵」などに変更した後に文字列の置換を行う方法がわかりません。前もって感謝します!

+0

(可能ならば全く...)アカデミック行使され、「リアルタイムで世界 "のようなエンジンを使うべきですhttp://freemarker.sourceforge.net –

答えて

3

使用この代わりに:次に

String regex = "\\$\\{([^}]*)\\}"; 

あなたは${とキャプチャグループ内の1

注意です}間のコンテンツのみを取得するそのパターンで特別な意味として$文字列の末尾
したがって、リテラル(中括弧)として見えるようにエスケープする必要があります。

+0

+1、あなたは正しいです、私のコメントを削除します。 – jlordo

6

は、なぜあなたは、そのファイルからのすべてのあなたのメッセージを得ることができる?その方法を.propertiesファイルを使用していないし、あなたのコードから分離することができ、(ファイルexample.properties)のようなもの:

message1=This is a {0} with format markers on it {1} 

そして、あなたのクラスであなたのバンドルをロードし、このようにそれを使用します。

ResourceBundle bundle = ResourceBundle.getBundle("example.properties", Locale.getDefault()); 
MessageFormat.format(bundle.getString('message1'), "param0", "param1"); // This gonna be your formatted String "This is a param0 with format markers on it param1" 

あなたが持つ、再びバンドルなしのMessageFormatを(java.utilのライブラリである)(単に直接文字列を使用)使用しますが、可能性がありあなたのコードを明確にします(そして簡単な国際化を提供します)

1

より良い使い方StrSubstitutor from apache commons lang。それはすることもでき、代替システムが完成するために

0

小道具、ここでは実用的なソリューションです:正規表現を使用してこの問題を解決しようとすると

static final Pattern EXPRESSION_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}"); 

/** 
* Replace ${properties} in an expression 
* @param expression expression string 
* @param properties property map 
* @return resolved expression string 
*/ 
static String resolveExpression(String expression, Map<String, String> properties) { 
    StringBuilder result = new StringBuilder(expression.length()); 
    int i = 0; 
    Matcher matcher = EXPRESSION_PATTERN.matcher(expression); 
    while(matcher.find()) { 
     // Strip leading "${" and trailing "}" off. 
     result.append(expression.substring(i, matcher.start())); 
     String property = matcher.group(); 
     property = property.substring(2, property.length() - 1); 
     if(properties.containsKey(property)) { 
      //look up property and replace 
      property = properties.get(property); 
     } else { 
      //property not found, don't replace 
      property = matcher.group(); 
     } 
     result.append(property); 
     i = matcher.end(); 
    } 
    result.append(expression.substring(i)); 
    return result.toString(); 
} 
関連する問題