melhor maneira de substituir todas as tags em uma string com java
-
03-07-2019 - |
Pergunta
Eu tenho um método de serviço que leva uma String e, em seguida, substitui as tags na seqüência com itens de uma biblioteca de tags. Da seguinte forma:
for( MetaDataDTO tag : tagValues )
{
message = message.replace( tag.getKey(), tag.getText1() );
}
Obviamente; isso faz montes de novas cordas e é ruim. Mas o StringBuilder substituir método é complicado de usar para várias cadeias dentro de uma string. Como posso fazer o meu método mais eficiente?
É para uso com blocos de texto, tais como:
Caro # firstName #, o seu pedido de # ApplicationType # tem sido # approvedRejected # arrependido.
Onde # firstName #, etc são as chaves em um banco de dados de dados meta. Também é possível que as etiquetas não podem ser cercado por personagens de hash.
Solução 2
Obrigado por sua ajuda caras. Certamente aprendi mais sobre java. Aqui está a minha solução. É desta forma para suportar diferentes marcas que procuram e tags dentro de tags:
private static String replaceAllTags(String message, Map< String, String > tags)
{
StringBuilder sb = new StringBuilder( message );
boolean tagFound = false;
/**
* prevent endless circular text replacement loops
*/
long recurrancyChecker = 5000;
do
{
tagFound = false;
Iterator it = tags.entrySet().iterator();
while( it.hasNext() )
{
Map.Entry pairs = (Map.Entry) it.next();
int start = sb.indexOf( pairs.getKey().toString() );
while( start > -1 && --recurrancyChecker > 0 )
{
int length = pairs.getKey().toString().length();
sb.replace( start, start + length, pairs.getValue().toString() );
start = sb.indexOf( pairs.getKey().toString() );
tagFound = true;
}
}
}
while( tagFound && --recurrancyChecker > 0 );
return sb.toString();
}
Outras dicas
Basicamente você deseja copiar a execução de Matcher.replaceAll () assim:
public static String replaceTags(String message, Map<String, String> tags) {
Pattern p = Pattern.compile("#(\\w+)#");
Matcher m = p.matcher(message);
boolean result = m.find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
m.appendReplacement(sb, tags.containsKey(m.group(1) ? tags.get(m.group(1)) : "");
result = m.find();
} while (result);
m.appendTail(sb);
message = sb.toString();
}
return message;
}
Nota: Eu fiz uma suposição sobre a tag válidos (ou seja, \ w na regex). Você vai precisar para atender esta para o que é realmente válido (por exemplo, "# ([\ w _] +) #").
Eu também assumiu as tags acima é algo como:
Map<String, String> tags = new HashMap<String, String>();
tags.add("firstName", "Skippy");
e não:
tags.add("#firstName#", "Skippy");
Se a segunda está correta você precisará ajustar em conformidade.
Este método faz exatamente uma passagem pela cadeia de mensagem para que ele não fica muito mais eficiente do que isso.