2017-05-31 51 views
0

替換佔位符與地圖值我想使用indexOf查找字符串中的佔位符(「$ {...}」)。 我下面的一個小例子很好地工作到目前爲止,但顯然只適用於第一次發生。我如何更改此代碼以便能夠遍歷所有佔位符並最終重建字符串。輸入字符串可以是隨機的,並且在其中沒有一定數量的佔位符。不確定該從哪裏出發。使用indexOf

// example Hashmap 
HashMap <String, String> placeHolderMap = new HashMap<String, String>(); 
placeHolderMap.put("name", "device"); 
placeHolderMap.put("status", "broken"); 
placeHolderMap.put("title", "smartphone"); 

// input String 
String content = "This ${name} is ${status} and categorized as ${title} in the system"; 
int left = content.indexOf("${"); 
int right = content.indexOf("}"); 

// getting the name of the placeholder, if the placeholdermap contains the placeholder as a key it sets the placeholder to the corresponding value 
String contentPlaceHolder = content.substring(left+2, right); 
if (placeHolderMap.containsKey(contentPlaceHolder)){ 
    contentPlaceHolder = placeHolderMap.get(contentPlaceHolder); 
} 
content = content.substring(0, left) + contentPlaceHolder + content.substring(right+1); 

目前,輸出將是 「此設備是$ {狀態}和歸類爲$ {標題}系統」

+0

怎麼樣[這個庫](https://github.com/holi-java/rstring/blob/master/src/test/java/com/holi/RStringVariableReplacementTest.java#L25-L29)?它是爲自己寫的。 –

回答

2

爲什麼不使用String.replaceAll()方法?

Map<String, String> placeHolderMap = new HashMap<>(); 
    placeHolderMap.put("\\$\\{name}", "device"); 
    placeHolderMap.put("\\$\\{status}", "broken"); 
    placeHolderMap.put("\\$\\{title}", "smartphone"); 


    // input String 
    String content = "This ${name} is ${status} and categorized as ${title} in the system"; 

    for (Map.Entry<String, String> entry : placeHolderMap.entrySet()) { 
      content = content.replaceAll(entry.getKey(), entry.getValue()); 
    } 

更新斯特凡,尼爾和肯尼特,謝謝。

UPDATE 17/07/17 您還可以使用與string.replace()方法,該方法不使用正則表達式,或者,使用Pattern.quote()方法:

Map<String, String> placeHolderMap = new HashMap<>(); 
    placeHolderMap.put("${name}", "device"); 
    placeHolderMap.put("${status}", "broken"); 
    placeHolderMap.put("${title}", "smartphone"); 


    // input String 
    String content = "This ${name} is ${status} and categorized as ${title} in the system"; 

    for (Map.Entry<String, String> entry : placeHolderMap.entrySet()) { 
      content = content.replace(entry.getKey(), entry.getValue()); 
      // content = content.replaceAll(Pattern.quote(entry.getKey()), entry.getValue()); 
    } 
+1

perfomance-hint:遍歷'placeHolderMap.entrySet()' –

+2

字符串是不可變的,因此如果不保留返回值,則調用「replaceAll」不起任何作用。 – Neil

+2

String.replaceAll使用正則表達式並給出java.util.regex.PatternSyntaxException:在索引0附近發生非法重複操作 $ {title}當您從OP中更改佔位符鍵時 – Kennet

0

您需要recusively調用你的方法:

private String replace(String content) { 
    int left = content.indexOf("${"); 
    if (left < 0) { 
     // breaking the recursion 
     return content; 
    } 
    int right = content.indexOf("}"); 

    // getting the name of the placeholder, if the placeholdermap contains the placeholder as a key it sets the placeholder to the corresponding value 
    String contentPlaceHolder = content.substring(left + 2, right); 
    if (placeHolderMap.containsKey(contentPlaceHolder)) { 
     contentPlaceHolder = placeHolderMap.get(contentPlaceHolder); 
    } 
    content = content.substring(0, left) + contentPlaceHolder + content.substring(right + 1); 
    return replace(content); 
} 
+0

這可能工作,但肯定「replaceAll」會比indexOf和遞歸調用更優雅的解決方案? – Neil

+0

@Neil如果它是作業,它被指定不使用'replaceAll'?它只是使用OP的規格 –

+0

@Neil「replaceAll」也有缺點。因爲如果一個字符串有重複的佔位符,它會表現錯誤。 –