如何使用参数名称而不是数字格式化消息?

我有这样的东西:

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

这对我来说并不好,因为有时我的翻译人员不确定{0}和{1}中的内容,也不用担心参数的顺序而改写消息。

我想用可读的名称而不是数字replace参数。 像这样的东西:

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

是否有捷径可寻?

谢谢! 抢

你可以使用MapFormat。 在这里find细节:

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

 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"); System.out.println("1st : " + MapFormat.format(text, map)); 

输出:第一:用户罗伯特有电子邮件地址rhume55@gmail.com。

请参阅org.apache.commons.lang3 StrSubstitutor :

 Map valuesMap = HashMap(); 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); // resolvedString: "The quick brown fox jumped over the lazy dog." 

容易做一个你自己。 这就是我使用的( main()函数仅用于testing代码):

 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)); } } 

您的问题与以下方面密切相关: 如何replaceJavastring中的一组令牌您可以使用velocity或其他模板库。 但是会有一些痛苦,因为Java没有任何一种Map文字。

 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; } 

但是你放弃所有的格式选项(如##。#)

我知道我的答案有点晚,但如果你仍然需要这个function,而不需要下载一个完整的模板引擎,你可以看看aleph-formatter (我是其中一个作者):

 Student student = new Student("Andrei", 30, "Male"); String studStr = template("#{id}\tName: #{st.getName}, Age: #{st.getAge}, Gender: #{st.getGender}") .arg("id", 10) .arg("st", student) .format(); System.out.println(studStr); 

或者你可以链接参数:

 String result = template("#{x} + #{y} = #{z}") .args("x", 5, "y", 10, "z", 15) .format(); System.out.println(result); // Output: "5 + 10 = 15" 

在内部,它使用一个StringBuilder,通过“parsing”expression式来创build结果,没有string连接,正则expression式/replace被执行。