首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MessageFormat中的嵌套选择子句?

MessageFormat中的嵌套选择子句?
EN

Stack Overflow用户
提问于 2014-04-07 12:55:29
回答 2查看 2.7K关注 0票数 11

我试图用java.text.MessageFormat来做一个简单的逻辑:

代码语言:javascript
复制
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个,则打印“多于4个”。

我发现没有人说这是不可能的,但我得到了一个IllegalArgumentException:

Choice Pattern incorrect: 1<hello|5<{1,choice,1<more than one|4<more than four}

有办法让我这么做吗?谢谢!

整个堆叠痕迹:

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-25 15:03:15

如果像这样编写模式,ChoiceFormat就无法解析格式,因为它无法知道控制字符(如格式分隔符(|)是用于内部格式还是外部格式)。但是,如果引用嵌套的格式,则可以告诉解析器,引用的文本不包含它应该解析的任何控制字符。然后,ChoiceFormat只返回包含另一个ChoiceFormat模式的文本。

如果MessageFormat类应用了ChoiceFormat,它再次将结果解析为MessageFormat,以处理附加的参数处理,然后处理内部ChoiceFormat

因此,如果您编写这样的模式,代码就会工作:

代码语言:javascript
复制
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));
票数 13
EN

Stack Overflow用户

发布于 2020-06-27 16:25:16

正如@Reboot所提到的,与这些类混淆的部分原因是ChoiceFormat在这里被MessageFormat.subformat()特别处理:

代码语言:javascript
复制
        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包含本身包含MessageFormatChoiceFormat

代码语言:javascript
复制
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。这使我可以定义如下消息:

代码语言:javascript
复制
<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&lt;">
            <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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22913055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档