我正在尝试用java.text.MessageFormat:
做一个简单的逻辑MessageFormat cf = new MessageFormat(
"{0,choice, 1<hello|5<{1,choice,1<more than one|4<more than four}}");
Object[] array = {3, 1};
System.out.println(cf.format(array));
使用单词:如果第一个参数大于1,则打印“hello”,如果大于5则打印第二个参数大于1打印“多于一个”如果第二个参数大于4打印“四个以上“。
我发现没有人说这是不可能的,但我得到了IllegalArgumentException:
Choice Pattern incorrect: 1<hello|5<{1,choice,1<more than one|4<more than four}
我有办法做到这一点吗?谢谢!
整个堆栈跟踪:
Exception in thread "main" java.lang.IllegalArgumentException: Choice Pattern incorrect: 1<hello|5<{1,choice,1<more than one|4<more than four}
at java.text.MessageFormat.makeFormat(Unknown Source)
at java.text.MessageFormat.applyPattern(Unknown Source)
at java.text.MessageFormat.<init>(Unknown Source)
at test.Test5.main(Test5.java:18)
Caused by: java.lang.IllegalArgumentException
at java.text.ChoiceFormat.applyPattern(Unknown Source)
at java.text.ChoiceFormat.<init>(Unknown Source)
... 4 more
答案 0 :(得分:9)
如果您编写这样的模式,ChoiceFormat
无法解析格式,因为它无法知道格式分隔符(|
)之类的控制字符是用于内部格式还是外部格式格式。但是如果你引用嵌套的格式,你可以告诉解析器引用的文本不包含它应该解析的任何控制字符。然后ChoiceFormat
将返回包含其他ChoiceFormat
模式的文字。
如果MessageFormat
类应用ChoiceFormat
,它会再次将结果解析为MessageFormat
以处理其他参数处理,然后处理内部ChoiceFormat
。
因此,如果你编写这样的模式代码就可以了:
MessageFormat cf = new MessageFormat(
"{0,choice, 1<hello|5<'{1,choice,1<more than one|4<more than four}'}");
Object[] array = {3, 1};
System.out.println(cf.format(array));
答案 1 :(得分:1)
如@Reboot所述,与这些类混淆的部分原因是ChoiceFormat
在这里特别MessageFormat.subformat()
被对待:
subFormatter = formats[i];
if (subFormatter instanceof ChoiceFormat) {
arg = formats[i].format(obj);
if (arg.indexOf('{') >= 0) {
subFormatter = new MessageFormat(arg, locale);
obj = arguments;
arg = null;
}
}
此骇客是允许MessageFormat
包含ChoiceFormat
本身包含MessageFormat
的原因:
new ChoiceFormat("0#none|1#one|1<{0}").format(3); // "{0}"
new MessageFormat("{0,choice,0#none|1#one|1<{0}}").format(new Object[] { 3 }); // "3"
当然,在特殊情况下,嵌套在ChoiceFormat
中的MessageFormat
可能包含嵌套的ChoiceFormat
,只要您正确地转义/引用即可。
这些类在语法/解析方面非常繁琐。与Java或bash的解析/转义/引用是“嵌套”不同,此处的解析是“渴望” ...但是可以。
我写了一些课程来帮助消除这种疯狂。这些课程不会尝试重新发明轮子。它们只是使已经存在的基础结构和嵌套可见。但是它们允许您绕过所有引号问题,并且它们支持任意嵌套深度。
在我自己的项目中,我已将它们连接为XML。这使我可以定义如下消息:
<message key="how.many.items">
<text>There </text>
<choice argnum="0">
<option limit="0">
<text>are no items</text>
</option>
<option limit="1">
<text>is one item</text>
</option>
<option limit="1<">
<text>are </text>
<choice argnum="0">
<option limit="0">
<number argnum="0"/>
</option>
<option limit="100">
<text>way too many</text>
</option>
</choice>
<text>items</text>
</option>
</choice>
<text>.</text>
</message>
有关详细信息,请参见MessageFmt。