62 votes

Comment formater un message avec des noms d'arguments au lieu de nombres?

J'ai quelque chose comme:

 String text = "The user {0} has email address {1}."
// params = { "Robert", "rhume55@gmail.com" }
String msg = MessageFormat.format(text, params);
 

Ce n'est pas génial pour moi, car parfois mes traducteurs ne sont pas sûrs de ce qui se passe dans les {0} et {1}, il serait également agréable de pouvoir reformuler les messages sans se soucier de l'ordre des arguments.

Je voudrais remplacer les arguments par des noms lisibles au lieu de nombres. Quelque chose comme ça:

 String text = "The user {USERNAME} has email address {EMAILADDRESS}."
// Map map = new HashMap( ... [USERNAME="Robert", EMAILADDRESS="rhume55@gmail.com"]
String msg = MessageFormat.format(text, map);
 

Y a-t-il un moyen facile de faire ceci?

Merci! Rob

35voto

GuruKulki Points 7974

Vous pouvez utiliser MapFormat pour cela. Découvrez les détails ici.

http://www.java2s.com/Code/Java/I18N/AtextformatsimilartoMessageFormatbutusingstringratherthannumerickeys.htm

Je posterai bientôt un exemple.

 String text = "The user {name} has email address {email}.";
            Object[] params = { "nameRobert", "rhume55@gmail.com" };
            Map map = new HashMap();
            map.put("name", "Robert");
            map.put("email", "rhume55@gmail.com");
            //String msg = MessageFormat.format(text, params);

            //System.out.println("1st : " + msg);

            System.out.println("1st : " + MapFormat.format(text, map));
 

SORTIE: 1er: L'utilisateur Robert a l'adresse e-mail rhume55@gmail.com.

10voto

Jason S Points 58434

Facile à faire vous-même. C'est ce que j'utilise (la fonction main() est juste pour le code de test):

 import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringTemplate {
    final private String template;
    final private Matcher m;
    static final private Pattern keyPattern = 
        Pattern.compile("\\$\\{([a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)*)\\}");
    private boolean blanknull=false;

    public StringTemplate(String template) { 
        this.template=template;
        this.m = keyPattern.matcher(template);
    }

    /**
     * @param map substitution map
     * @return substituted string
     */
    public String substitute(Map<String, ? extends Object> map)
    {
        this.m.reset();
        StringBuffer sb = new StringBuffer();
        while (this.m.find())
        {
            String k0 = this.m.group();
            String k = this.m.group(1);
            Object vobj = map.get(k);
            String v = (vobj == null) 
                ? (this.blanknull ? "" : k0)
                : vobj.toString();
            this.m.appendReplacement(sb, Matcher.quoteReplacement(v));
        }
        this.m.appendTail(sb);
        return sb.toString();       
    }

    public StringTemplate setBlankNull()
    {
        this.blanknull=true;
        return this;
    }

    static public void main(String[] args)
    {
        StringTemplate t1 = new StringTemplate("${this} is a ${test} of the ${foo} bar=${bar} ${emergency.broadcasting.system}");
        t1.setBlankNull();
        Map<String, String> m = new HashMap<String, String>();
        m.put("this", "*This*");
        m.put("test", "*TEST*");
        m.put("foo", "$$$aaa\\\\111");
        m.put("emergency.broadcasting.system", "EBS");
        System.out.println(t1.substitute(m));
    }
}
 

1voto

kevin cline Points 1300

Votre question est étroitement liée à: Comment remplacer un ensemble de jetons dans une chaîne Java Vous pouvez utiliser Velocity ou une autre bibliothèque de modèles. Mais il y aura de la peine car Java n'a aucun type de littéraux Map.

0voto

GKislin Points 254
 static final Pattern REPLACE_PATTERN = Pattern.compile("\\x24\\x7B([a-zA-Z][\\w\\x2E].*?)\\x7D");

/**
 * Check for unresolved environment
 *
 * @param str
 * @return origin if all substitutions resolved
 */
public static String checkReplacement(String str) {
    Matcher matcher = REPLACE_PATTERN.matcher(str);
    if (matcher.find()) {
        throw LOG.getIllegalArgumentException("Environment variable '" + matcher.group(1) + "' is not defined");
    }
    return str;
}

// replace in str ${key} to value
public static String resolveReplacement(String str, Map<String, String> replacements) {
    Matcher matcher = REPLACE_PATTERN.matcher(str);
    while (matcher.find()) {
        String value = replacements.get(matcher.group(1));
        if (value != null) {
            str = matcher.replaceFirst(replaceWindowsSlash(value));
        }
    }
    return str;
}
 

Mais vous perdez toutes les options de format (comme ##. #)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X