在ICU中,数字是根据适用于区域设置的模式和数字符号进行解析的。在解析数字时,我们需要宽大一些,但不要太过宽大,以致于我们会解释可能的错误,例如“1.1”在法语中被解释为11(就像ICU最新的现成版本一样)。以下是关于如何做到这一点的一些想法。
我们允许在模式的数字元素中使用的字符之间有一些等效性。分隔符分为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();
前两个符号可以是十进制符号,也可以是分组符号;其他符号只能是分组符号。因此,对于特定的区域设置,我们可以只包含前两个符号中的一个作为十进制符号(基于区域设置数据),而所有其他符号作为分组符号。但是,我们需要对这些符号进行一些限制:
可以有零或一个十进制符号,但不能有更多。我们确实允许最后一个十进制符号(例如“2.0”、“2”或“2”,所有解析都相同)
分组符号可能完全缺失(例如“12345”)
如果有多个分组符号,它们必须是完全相同的字符(例如既不是“1234567”也不是“1·234”567")
如果有分组符号,则间隔必须是以下之一,而不是其他间隔(例如,不是“1234,56”、“12,34”或“1,2”)
每三次,或
每四次,或
印度教风格(两个,然后三个)。
小数点后不允许使用分组符号(例如,不允许使用“1.234567890”)
其他项目:
允许空白作为前导、尾随或元素之间(例如货币和数字之间,或“(”和数字之间等)。
除了显式的负数格式(如“0.0;(0.0)”)之外,我们还应该始终允许正数格式之前或之后的减号(如果有减号,则在数字和货币符号之间)作为负数。因此,对于上面的示例,我们将解析“(12)”或“-12”或“12-”。
解析是区分大小写的(主要是针对货币的问题)。
货币允许使用货币符号、国际符号或名称。
数字可以来自任何十进制集合(http://unicode.org/cldr/utility/list-unicodest.jsp?a=\p{nd}),但必须全部来自同一集合。
在没有ParsePosition的API方法中(或在其他方法中为null),任何尾随字符(空白除外)都会导致错误。
注意:我认为我们已经测试了模式,以确保它们是健全的,例如没有“###-hi-mom-##0”。
我们还对其他常见元素使用等价物:
我们可能应该要求将等效数据添加到CLDR中,但应添加到补充数据中;我们不希望它因地区而异。
严格的解析要求字符完全匹配(没有等价项),但允许在空格(数字内除外)和分组(受上述约束)中具有上述灵活性。数字可以来自ASCII或区域设置的本地集,但不能来自其他集;他们一定都来自同一组。
问题:我们应该使解析成为规范/兼容性-等效不敏感的吗?我最初的想法是,我们可以调整等价集以获得最大的好处,也许还可以使用货币做一些事情,但不是为了实现完全规范/兼容-等价不敏感。