java-如何用参数名称而不是数字格式化消息?
我有类似的东西:
String text = "The user {0} has email address {1}."
// params = { "Robert", "myemailaddr@gmail.com" }
String msg = MessageFormat.format(text, params);
这对我来说不是很好,因为有时我的翻译人员不确定{0}和{1}中的内容,因此能够重新编写消息而不必担心args的顺序也很不错。
我想将参数替换为可读的名称而不是数字。 像这样:
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);
是否有捷径可寻?
谢谢!抢
6个解决方案
29 votes
您可以为此使用MapFormat。 在此处查找详细信息:
[http://www.java2s.com/Code/Java/I18N/Atextformat与MessageFormat类似,但使用的是字符串而不是数字键。
String text = "The user {name} has email address {email}.";
Map map = new HashMap();
map.put("name", "Robert");
map.put("email", "rhume55@gmail.com");
System.out.println("1st : " + MapFormat.format(text, map));
输出:
1st:用户Robert的电子邮件地址为rhume55@gmail.com。
GuruKulki answered 2020-01-10T04:26:45Z
17 votes
请参阅来自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."
AlikElzin-kilaka answered 2020-01-10T04:27:05Z
11 votes
容易使自己。 这就是我使用的(main()函数仅用于测试代码):
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 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 m = new HashMap();
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));
}
}
Jason S answered 2020-01-10T04:27:26Z
2 votes
您的问题与以下主题密切相关:如何替换Java字符串中的一组标记您可以使用力度或其他模板库。 但是会有些痛苦,因为Java没有任何Map文字。
kevin cline answered 2020-01-10T04:27:47Z
2 votes
我知道我的答案来得有点晚,但是如果您仍然需要此功能,而无需下载完整的模板引擎,则可以看看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来工作,它通过“解析”表达式来创建结果,不执行任何字符串连接,正则表达式/替换。
Andrei Ciobanu answered 2020-01-10T04:28:16Z
1 votes
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 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;
}
但是您会丢失所有格式选项(例如##。#)
GKislin answered 2020-01-10T04:28:36Z