我应该在没有占位符的本地化消息中使用java.text.MessageFormat吗?

11

我们正在为一个运行在Java 5上的网页应用程序本地化用户界面文本,并且遇到了一个难题,即如何输出在属性文件中定义的消息 - 这种类型的消息通常使用 java.util.Properties

有些消息包括一个占位符,该占位符将使用java.text.MessageFormat来填充。例如:

search.summary = Your search for {0} found {1} items.

MessageFormat 很让人恼火,因为单引号是特殊字符,尽管在英文文本中很常见。你必须输入两个单引号来表示一个字面单引号:

warning.item = This item''s {0} is not valid.

然而,该应用程序约1000条消息中有四分之三不包括占位符。这意味着我们可以直接输出它们,避免使用 MessageFormat,并保留单引号:

help.url = The web page's URL

问题:我们是否应该对所有消息使用MessageFormat,以实现统一的语法,还是尽可能避免使用MessageFormat,以便大多数消息不需要转义?

显然,两种方法都有优缺点。

请注意,MessageFormat的API文档承认了这个问题,并建议不要解决:

在消息格式模式中使用引号的规则不幸地显示出相当令人困惑。特别是,本地化人员并不总是清楚单引号是否需要加倍。确保向本地化人员告知规则,并通过在资源束源文件中使用注释来告诉他们哪些字符串将由MessageFormat处理。

5个回答

2
最终我们决定通过始终使用“卷曲”引号来避免单引号问题:
warning.item = This item\u2019s {0} is not valid.

2

不要使用这个令人恼火的功能,自己编写MessageFormat的实现。您可以查看SLF4J Logger的代码。

他们有自己的消息格式化程序版本,可以按以下方式使用:

logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

空占位符可与默认排序一起使用,并且在某些本地化情况下进行编号,其中不同的语言对单词或句子的部分进行排列。


可以使用那个库来仅仅格式化一个字符串吗? - Peter Hilton
看起来这个机制深深地嵌入到代码中了。也许你会更幸运:http://logback.qos.ch/download.html - Boris Pavlović
确实,那我想我会寻找另一种实现方式。 - Peter Hilton

1

在引用时,请使用 ` 字符而不是 ' 字符。我们经常使用它而没有任何问题。

只有在需要时才使用 MessageFormat,否则它们只会使代码变得臃肿,并且没有额外的价值。


0
在我看来,一致性对于这种事情很重要。属性文件和MessageFormat已经有很多限制了。如果你觉得这些问题困扰你,可以“编译”你的属性文件以生成格式正确的文件。但是我建议在任何地方都使用MessageFormat。这样,在维护代码时,你不需要担心哪些字符串被格式化,哪些没有。它变得更简单处理,因为你可以将消息处理交给库来处理,而不用在高层次上担心细节。

-1

另一个选择是...在加载属性文件时,只需将输入流包装在一个FilterInputStream中,它会将每个单引号加倍。


并非他所有的消息都需要两个单引号。这意味着他必须在消息格式字符串中进行识别的黑客行为。哎呀。 - JonMR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接