meilleur moyen de remplacer toutes les balises d'une chaîne par java
-
03-07-2019 - |
Question
J'ai une méthode de service qui prend une chaîne, puis remplace les balises dans la chaîne par des éléments d'une bibliothèque de balises. Comme suit:
for( MetaDataDTO tag : tagValues )
{
message = message.replace( tag.getKey(), tag.getText1() );
}
évidemment; cela fait des tas de nouvelles chaînes et est mauvais. Mais la méthode de remplacement de StringBuilder est difficile à utiliser pour plusieurs chaînes dans une chaîne. Comment puis-je rendre ma méthode plus efficace?
Il est destiné à être utilisé avec des blocs de texte tels que:
Cher # prenom #, votre application pour # applicationType # a été # approuvéeRejetée # désolée.
Où # prénom #, etc. sont les clés d'une base de métadonnées. Il est également possible que les balises ne soient pas entourées de caractères de hachage.
La solution 2
Merci pour votre aide les gars. Certainement appris plus sur java. Voici ma solution. C’est cette façon de prendre en charge différents tags de recherche et tags dans les 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();
}
Autres conseils
En gros, vous voulez copier l'exécution de Matcher.replaceAll () comme suit:
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;
}
Remarque: j'ai émis une hypothèse concernant la balise valide (à savoir \ w dans la regex). Vous devrez en tenir compte pour ce qui est vraiment valable (par exemple, "# ([\ w _] +) #").
J'ai également supposé que les balises ci-dessus ressemblaient à:
Map<String, String> tags = new HashMap<String, String>();
tags.add("firstName", "Skippy");
et non:
tags.add("#firstName#", "Skippy");
Si la seconde est correcte, vous devrez vous adapter en conséquence.
Cette méthode effectue exactement un passage sur la chaîne de message, de sorte qu'elle ne soit pas plus efficace que cela.