Remplacement de chaîne de caractères en java, similaire à un modèle velocity
Existe-t-il un mécanisme de remplacement String
en Java, où je peux passer des objets avec un texte, et il remplace la chaîne de caractères telle qu'elle apparaît.
Par exemple, le texte est :
Hello ${user.name},
Welcome to ${site.name}.
les objets que j'AI sont "user"
et "site"
. Je veux remplacer les chaînes données dans ${}
par les valeurs équivalentes des objets. C'est la même chose que nous remplaçons les objets dans un modèle de vitesse.
6 réponses
l'Utilisation d'apache commons lang.
https://commons.apache.org/proper/commons-lang /
il le fera pour vous (et son open source...)
Map<String, String> valuesMap = new HashMap<String, String>();
valuesMap.put("animal", "quick brown fox");
valuesMap.put("target", "lazy dog");
String templateString = "The ${animal} jumped over the ${target}.";
StrSubstitutor sub = new StrSubstitutor(valuesMap);
String resolvedString = sub.replace(templateString);
regardez la classe java.text.MessageFormat
, MessageFormat prend un ensemble d'objets, les formate, puis insère les chaînes formatées dans le modèle aux endroits appropriés.
Object[] params = new Object[]{"hello", "!"};
String msg = MessageFormat.format("{0} world {1}", params);
j'ai réuni une petite implémentation d'essai de ceci. L'idée de base est d'appeler format
et passer dans la chaîne de format, et une carte des objets, et les noms qu'ils ont localement.
la sortie de ce qui suit est:
mon chien s'appelle fido, et il appartient à Jane Doe.
public class StringFormatter {
private static final String fieldStart = "\$\{";
private static final String fieldEnd = "\}";
private static final String regex = fieldStart + "([^}]+)" + fieldEnd;
private static final Pattern pattern = Pattern.compile(regex);
public static String format(String format, Map<String, Object> objects) {
Matcher m = pattern.matcher(format);
String result = format;
while (m.find()) {
String[] found = m.group(1).split("\.");
Object o = objects.get(found[0]);
Field f = o.getClass().getField(found[1]);
String newVal = f.get(o).toString();
result = result.replaceFirst(regex, newVal);
}
return result;
}
static class Dog {
public String name;
public String owner;
public String gender;
}
public static void main(String[] args) {
Dog d = new Dog();
d.name = "fido";
d.owner = "Jane Doe";
d.gender = "him";
Map<String, Object> map = new HashMap<String, Object>();
map.put("d", d);
System.out.println(
StringFormatter.format(
"My dog is named ${d.name}, and ${d.owner} owns ${d.gender}.",
map));
}
}
Note: cela ne se compile pas en raison d'exceptions non compilées. Mais il fait le code beaucoup plus facile à lire.
en outre, je n'aime pas que vous ayez à construire la carte vous-même dans le code, mais je ne sais pas comment obtenir les noms des variables locales programatiquement. La meilleure façon de le faire, est de vous mettre l'objet dans la carte dès que vous créez.
L'exemple suivant produit les résultats que vous voulez à partir de votre exemple:
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
Site site = new Site();
map.put("site", site);
site.name = "StackOverflow.com";
User user = new User();
map.put("user", user);
user.name = "jjnguy";
System.out.println(
format("Hello ${user.name},\n\tWelcome to ${site.name}. ", map));
}
je devrais aussi mentionner que je n'ai aucune idée de la Vitesse, donc j'espère que cette réponse est pertinente.
voici un aperçu de la façon de procéder. Il devrait être relativement simple de l'appliquer en tant que code réel.
- Créer une carte de tous les objets qui seront référencés dans le modèle.
- utilisez une expression régulière pour trouver des références variables dans le modèle et les remplacer par leurs valeurs (voir étape 3). La classe Matcher sera pratique pour trouver-et-remplacer.
- divise le nom de la variable au point.
user.name
devientuser
etname
. Recherchezuser
dans votre carte pour obtenir l'objet et l'utilisation réflexion pour obtenir la valeur dename
de l'objet. En supposant que vos objets ont des getters standards, vous chercherez une méthodegetName
et l'invoquerez.
il y a quelques implémentations de langage D'Expression là-bas qui fait cela pour vous, pourrait être préférable d'utiliser votre propre implémentation comme ou si vos exigences augmentent, voir par exemple JUEL et MVEL
j'aime et ai utilisé avec succès MVEL dans au moins un projet.
Also see the Stackflow post JSTL / JSP EL (Expression Language) in a non JSP (standalone) contexte
il n'y a rien dans la boîte qui soit comparable à la vitesse puisque la vitesse a été écrite pour résoudre exactement ce problème. La chose la plus proche que vous pouvez essayer est de regarder dans le Formatteur
cependant le formatteur autant que je sache a été créé pour fournir des options de formatage C comme en Java donc il ne peut pas égratigner exactement votre démangeaisons, mais vous êtes les bienvenus pour essayer :).