10

我正在尝试使用 intl 包中的 NumberFormatter 类将整数数量拼写为斯洛文尼亚语单词(用于邮政声明),但结果完全错误且毫无意义。

$fmt = new NumberFormatter('sl', NumberFormatter::SPELLOUT);
$fmt->format(561);

结果是“petsto šestdeset ena”,而它应该是“petsto enainšestdeset”。看起来像婴儿说话。

在非常相似的克罗地亚语中,结果似乎还可以(“petsto šezdeset i jedan”)。

这是在 PHP 中做的不好的翻译还是基于我的系统语言环境?我在 PHP 5.3.10 / Ubuntu 12.04 上。

编辑:

intl 是 1.1.0 版本,当前是 3.0.0,所以也许它已经修复了?

4

1 回答 1

5

免责声明 - 我不会说斯洛文尼亚语或克罗地亚语。

看起来 PHP 扩展用于这些语言中的数字的模式存在一些差距。要了解我的意思,您可以通过运行显示使用的模式:

$fmt = new NumberFormatter('sl', NumberFormatter::SPELLOUT);
echo $fmt->getPattern();

如果您查看此输出,您可能会发现“%spellout-cardinal-masculine:”的一部分似乎从大约 30 跳到 100。

...
    21: dvaset >%spellout-cardinal-masculine>;
    30: <%spellout-cardinal-masculine<deset;
    31: <%spellout-cardinal-masculine<deset >%spellout-cardinal-masculine>;
    100: sto;
    101: sto >%spellout-cardinal-masculine>;
    200: dvjesto;
...

这意味着没有为高于 31 和低于 100 的数字定义规则。您输出的数字的“61”部分属于这个差距。

您可以生成自己的模式来解决这个问题 - 我粘贴了 en-US 格式化程序的模式并稍微调整了一下,所以它看起来像这样:

...
    21: dvaset >%spellout-cardinal-masculine>;
    30: <%spellout-cardinal-masculine<deset;
    31: <%spellout-cardinal-masculine<deset >%spellout-cardinal-masculine>;
    40: forty;
    41: forty->%spellout-cardinal-masculine>;
    50: fifty;
    51: fifty->%spellout-cardinal-masculine>;
    60: sixty;
    61: sixty->%spellout-cardinal-masculine>;
    70: seventy;
    71: seventy->%spellout-cardinal-masculine>;
    80: eighty;
    81: eighty->%spellout-cardinal-masculine>;
    90: ninety;
    91: ninety->%spellout-cardinal-masculine>;
    100: sto;
    101: sto >%spellout-cardinal-masculine>;
    200: dvjesto;
...

现在,如果我将其保存在一个名为 sl.txt 且采用 UTF-8 编码的新文件中,我可以将其加载到 NumberFormatter 中:

$pattern = file_get_contents('sl.txt')
$fmt = new NumberFormatter('sl', NumberFormatter::PATTERN_RULEBASED, $pattern);
echo($fmt->format(561));

这给了我以下输出:

petsto sixty-ena

当然,这是错误的 - 它是斯洛文尼亚语和英语的混合体,但我认为如果您将格式编辑为如下所示:

...
    61: >%spellout-cardinal-masculine>inšestdeset;
...

正如我所说,我不会说斯洛文尼亚语,所以你可能想检查一下。但这会给你以下输出:

petsto enainšestdeset

您需要为 31-100 的每个缺失的数字块添加此规则。您可能还想检查ICU 文档以了解基于规则的格式,以确保您得到正确的格式。

这是一个错误,但在 PHP 中没有 - 如果您想修复它,那么问题出在文件中Unicode 的通用语言环境数据存储库中。PHP 的 intl 使用 ICU,它使用 CLDR 数据。

于 2013-11-18T17:45:08.157 回答