2013-06-27 13 views
5

Będą podane ciągi zawierające sformatowane "właściwości"; czyli Struny obudowane wewnątrz standardu "$ {" i "}" tokeny:Wyszukaj i zamień sformatowane właściwości wewnątrz łańcucha znaków Java

"Jest to $ {example} z $ {ciąg} abym $ {} podano."

będę mieć także HashMap<String,String> zawierające podstawienia dla każdej możliwej sformatowanej nieruchomości:

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

Tak, że, biorąc pod uwagę następujący ciąg:

„Lubię jeść $ {boczek} i $ {ham}. "

mogę wysłać to do metody Java, która będzie przekształcić go na: "Lubię jeść jajka i sałatki"

Oto moja najlepsza próba:

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..."); 

Kiedy wykonać to otrzymuję żadnych błędów, ale po prostu zobaczyć "Uruchamianie ..." i "zakończenia ..." wyjścia. To mówi mi, że moje wyrażenie regularne jest niepoprawne, a więc Matcher nie jest w stanie dopasować żadnych właściwości.

Moje pierwsze pytanie brzmi: co to powinno być?

Kiedy już przeszłam, nie jestem pewien, jak wykonać ciąg zastępowania po zmianie "$ {bacon}" na "jaja" itd. Jakieś pomysły? Z góry dziękuję!

+0

Próbując rozwiązać ten problem z RegEx (jeśli to w ogóle możliwe ...) jest ćwiczeniem akademicki „, w prawdziwym świat "powinieneś używać silnika takiego jak np http://freemarker.sourceforge.net –

Odpowiedz

3

Użyj tego zamiast:

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

Następnie można uzyskać tylko zawartość między ${ i } który jest wewnątrz grupy przechwytującej 1.

Zauważ, że $ jako szczególnego znaczenia w strukturze: koniec łańcucha
W ten sposób musi być unikany, aby być postrzeganym jako literalny (jako nawiasy klamrowe).

+0

+1, Masz rację, usuwając mój komentarz. – jlordo

6

Dlaczego nie użyć pliku .properties ?, w ten sposób można uzyskać wszystkie wiadomości z tego pliku i może być oddzielony od kodu, coś jak (example.properties plików):

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

a następnie w klasie załadować swój tobołek i używać go tak:

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" 

można użyć MessageFormat (jest biblioteką java.util) bez wiązki (wystarczy użyć String bezpośrednio), ale znowu, posiadające pakiet sprawia, że ​​twój kod jest jasny (i daje łatwą internacjonalizację)

1

Lepiej używać StrSubstitutor od Apache commons lang.Może on również zastępować systemu rekwizyty

0

Na zakończenie, o to roztwór roboczy:

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(); 
} 
Powiązane problemy