Grazie a tutti per le risposte!
La risposta di Gizmo era decisamente fuori dagli schemi e un'ottima soluzione, ma sfortunatamente non appropriata in quanto il formato non può essere limitato a ciò che la classe del formatore fa in questo caso.
Adam Paynter è arrivato davvero al cuore della questione, con lo schema giusto.
Peter Nix e Sean Bright hanno avuto una soluzione eccezionale per evitare tutte le complessità della regex, ma avevo bisogno di aumentare alcuni errori se c'erano cattivi token, cosa che non andava.
Ma in termini di una regex e un ciclo di sostituzione ragionevole, questa è la risposta che ho trovato (con un piccolo aiuto da parte di Google e la risposta esistente, compreso il commento di Sean Bright su come usare group (1) vs gruppo()):
private static Pattern tokenPattern = Pattern.compile("\\{([^}]*)\\}");
public static String process(String template, Map<String, Object> params) {
StringBuffer sb = new StringBuffer();
Matcher myMatcher = tokenPattern.matcher(template);
while (myMatcher.find()) {
String field = myMatcher.group(1);
myMatcher.appendReplacement(sb, "");
sb.append(doParameter(field, params));
}
myMatcher.appendTail(sb);
return sb.toString();
}
Dove doParameter ottiene il valore di mappa e lo converte in una stringa e genera un'eccezione se non è lì.
Nota inoltre ho modificato il modello per trovare le parentesi graffe vuote (ad esempio {}), poiché si tratta di una condizione di errore verificata esplicitamente.
MODIFICA:
Nota che appendReplacement non è agnostico sul contenuto della stringa. Per javadocs, riconosce $ e backslash come carattere speciale, quindi ho aggiunto un po 'di escape per gestirlo nell'esempio sopra. Non fatto nel modo più consapevole delle prestazioni, ma nel mio caso non è un affare abbastanza grande per valere la pena di tentare di micro-ottimizzare le creazioni di stringhe.
Grazie al commento di Alan M, questo può essere reso ancora più semplice per evitare i problemi di carattere speciale di appendReplacement.
provare http://github.com/niesfisch/tokenreplacer/ – Marcel