2014-10-06 4 views
2

Я хотел бы найти строки, которые заключены в ${...}, и использовать эти строки как ключи для HashMap, который содержит значения, которые я хотел бы использовать для замены ${...}.Как использовать обратную ссылку для замены строки в качестве ключа для HashMap в Java?

В следующем примере строка Master_${field1}_${field2}_End должна быть преобразована в Master_slave1_slave2_End:

package com.stackoverflow; 

import java.util.HashMap; 
import java.util.Map; 

public class RegExReplace { 

    public static void main(String[] args) { 
//  String string = "Master_${field1}_${field2}_${nonexisting}_End"; 
     String string = "Master_${field1}_${field2}_End"; 
     Map<String, String> toBeInserted = new HashMap<String, String>(); 
     toBeInserted.put("field1", "slave1"); 
     toBeInserted.put("field2", "slave2"); 
     toBeInserted.put("field3", "slave3"); 

     String pattern = "\\$\\{([a-zA-Z0-9\\-_]*)\\}"; 
     String replace = "$1"; 

//  System.out.println(string.replaceAll(pattern, replace)); 
     System.out.println(string.replaceAll(pattern, toBeInserted.get(replace))); 

    } // END: main() 

} // END: class 

(Как) это возможно, использовать в качестве обратной ссылки ключа для HashMap?

+0

Вы можете создать другую строку: 'String mapKey = string.replaceAll (pattern," $ 1 ")', а затем использовать 'mapKey' во второй замене – BackSlash

ответ

3

Вы можете использовать итерации над матчами вашей Pattern и StringBuffer для добавления замены, как таковой:

String string = "Master_${field1}_${field2}_End"; 
Map<String, String> toBeInserted = new HashMap<String, String>(); 
toBeInserted.put("field1", "slave1"); 
toBeInserted.put("field2", "slave2"); 
toBeInserted.put("field3", "slave3"); 

Pattern p = Pattern.compile("\\$\\{(.+?)\\}"); 
Matcher m = p.matcher(string); 
StringBuffer sb = new StringBuffer(); 
while (m.find()) { 
    String key = m.group(1); 
    if (key != null) { 
     String value = toBeInserted.get(key); 
     if (value != null) 
      m.appendReplacement(sb, value); 
    } 
} 
m.appendTail(sb); 
System.out.println(sb.toString()); 

Выход

Master_slave1_slave2_End 
2

Вы на правильном пути, и ваше регулярное выражение выглядит хорошо.

Теперь следующие шаги:

  1. Компиляция строки регулярное выражение, чтобы сделать Pattern объект
  2. Создать Matcher экземпляр, передав в вашей входной строки для скомпилированного Pattern объекта (т.е. Matcher matcher = pattern.matcher(stringInput))
  3. Выполнить while (matcher.find()) {...} петля
  4. Внутри петлевого доступа matcher.group(1) (т.е. backreference) в качестве ключа к вашему HashMap

Собирая вообще:

Pattern p = Pattern.compile(pattern); 
Matcher m = p.matcher(string); 
StringBuffer sb = new StringBuffer(); 
while(m.find()) { 
    m.appendReplacement(sb, toBeInserted.get(m.group(1))); 
} 
m.appendTail(sb); 

System.out.println("Converted string is: " + sb.toString());