2013-06-27 90 views
5

我將給出包含格式化「屬性」的字符串;也就是說,封裝在標準「$ {」和「}」令牌內的字符串:搜索並替換Java字符串中的格式化屬性

「這是$ {string}的$ {example},我可能是$ {given}。」

我也將有一個HashMap<String,String>包含替換爲每個可能的格式屬性:

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

因此,鑑於以下字符串:

「我最喜歡吃$ {臘肉}和$ {ham}。「

我可以給這個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無法匹配任何屬性。

所以我的第一個問題是:這個正則表達式應該是什麼?

一旦我已經過去了,我不知道如何在將「$ {bacon}」變成「雞蛋」等任何想法?提前致謝!

+0

試圖解決這個問題,正則表達式(如果可能的話...)是一個跑位練習,「在現實世界「你應該使用像例如引擎http://freemarker.sourceforge.net –

回答

3

使用這個代替:

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

那麼你只能獲得${}這是捕獲組內1

注意的內容,該$作爲圖案的特殊含義:字符串末尾
因此,必須將其轉義爲文字(如大括號)。

+0

+1,你是對的,刪除我的評論。 – jlordo

6

爲什麼不使用屬性文件?這樣你可以得到從該文件中所有的消息,可能是從你的代碼分開,像(文件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庫)(只需直接使用String),但同樣,有捆綁使您的代碼清晰(並提供簡單的國際化)

1

更好地使用來自apache commons lang的StrSubstitutor。它還可以替代系統道具

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