数字解析

作者

日期

状态

马克·戴维斯

2009-06-19

建议书

在ICU中,数字是根据适用于区域设置的模式和数字符号进行解析的。在解析数字时,我们需要宽大一些,但不要太过宽大,以致于我们会解释可能的错误,例如“1.1”在法语中被解释为11(就像ICU最新的现成版本一样)。以下是关于如何做到这一点的一些想法。

Lenient分析

我们允许在模式的数字元素中使用的字符之间有一些等效性。分隔符分为4类,其中我们可以考虑等效项:

    • private final Unicode Set dotEquivalents=(Unicode Set)new Unicode Set(“[..․·.۔٬]”).freeze();

    • private final Unicode Set commaEquivalents=(Unicode Set)new Unicode Set(“[,,,,،、,؍]”).freeze();

    • private final Unicode Set撇号Equivalents=(Unicode Set)new Unicode Set(“[︑'''']”).freeze();

    • private final Unicode Set spaceEquivalents=(Unicode Set)new Unicode Set(“[:whitespace:]”).freeze();

前两个符号可以是十进制符号,也可以是分组符号;其他符号只能是分组符号。因此,对于特定的区域设置,我们可以只包含前两个符号中的一个作为十进制符号(基于区域设置数据),而所有其他符号作为分组符号。但是,我们需要对这些符号进行一些限制:

    1. 可以有零或一个十进制符号,但不能有更多。我们确实允许最后一个十进制符号(例如“2.0”、“2”或“2”,所有解析都相同)

    2. 分组符号可能完全缺失(例如“12345”)

    3. 如果有多个分组符号,它们必须是完全相同的字符(例如既不是“1234567”也不是“1·234”567")

    4. 如果有分组符号,则间隔必须是以下之一,而不是其他间隔(例如,不是“1234,56”、“12,34”或“1,2”)

      1. 每三次,或

      2. 每四次,或

      3. 印度教风格(两个,然后三个)。

    5. 小数点后不允许使用分组符号(例如,不允许使用“1.234567890”)

其他项目:

    1. 允许空白作为前导、尾随或元素之间(例如货币和数字之间,或“(”和数字之间等)。

    2. 除了显式的负数格式(如“0.0;(0.0)”)之外,我们还应该始终允许正数格式之前或之后的减号(如果有减号,则在数字和货币符号之间)作为负数。因此,对于上面的示例,我们将解析“(12)”或“-12”或“12-”。

    3. 解析是区分大小写的(主要是针对货币的问题)。

    4. 货币允许使用货币符号、国际符号或名称。

    5. 数字可以来自任何十进制集合(http://unicode.org/cldr/utility/list-unicodest.jsp?a=\p{nd}),但必须全部来自同一集合。

    6. 在没有ParsePosition的API方法中(或在其他方法中为null),任何尾随字符(空白除外)都会导致错误。

    7. 注意:我认为我们已经测试了模式,以确保它们是健全的,例如没有“###-hi-mom-##0”。

    8. 我们还对其他常见元素使用等价物:

      • private final UnicodeSet minusEquivalents=(UnicodeSet)new UnicodeGroup(“[:dash:]”).freeze();

      • private final Unicode Set openEquivalents=(Unicode Set)new Unicode Set(“[(❨(…]”).freeze();

      • ...

我们可能应该要求将等效数据添加到CLDR中,但应添加到补充数据中;我们不希望它因地区而异。

严格分析

严格的解析要求字符完全匹配(没有等价项),但允许在空格(数字内除外)和分组(受上述约束)中具有上述灵活性。数字可以来自ASCII或区域设置的本地集,但不能来自其他集;他们一定都来自同一组。

问题:我们应该使解析成为规范/兼容性-等效不敏感的吗?我最初的想法是,我们可以调整等价集以获得最大的好处,也许还可以使用货币做一些事情,但不是为了实现完全规范/兼容-等价不敏感。