为什么`'↊'.isnumeric()`false?

时间:2016-10-20 13:58:05

标签: python unicode

根据Official Unicode Consortium code chart,所有这些都是数字:

⅐   ⅑   ⅒   ⅓   ⅔   ⅕   ⅖   ⅗   ⅘   ⅙   ⅚   ⅛   ⅜   ⅝   ⅞   ⅟
Ⅰ   Ⅱ   Ⅲ   Ⅳ   Ⅴ   Ⅵ   Ⅶ   Ⅷ   Ⅸ   Ⅹ   Ⅺ   Ⅻ   Ⅼ   Ⅽ   Ⅾ   Ⅿ
ⅰ   ⅱ   ⅲ   ⅳ   ⅴ   ⅵ   ⅶ   ⅷ   ⅸ   ⅹ   ⅺ   ⅻ   ⅼ   ⅽ   ⅾ   ⅿ
ↀ   ↁ   ↂ   Ↄ   ↄ   ↅ   ↆ   ↇ   ↈ   ↉   ↊   ↋

然而,当我要求Python告诉我哪些是数字时,它们都是(偶数)除了四个:

In [252]: print([k for k in "⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻⅼⅽⅾⅿↀↁↂↃↄↅↆↇↈ↉↊↋" if not k.isnumeric()])
['Ↄ', 'ↄ', '↊', '↋']

那些是:

  • Ↄ罗马数字逆转了一百个
  • ↄ拉丁文小写字母反转C
  • ↊转数字二
  • ↋转数字三

为什么Python认为那些不是数字?

1 个答案:

答案 0 :(得分:10)

对于“具有Unicode数值属性的所有字符”,

str.isnumeric被记录为真。

该属性的规范参考是Unicode Character Database。我们需要的信息可以从http://www.unicode.org/Public/9.0.0/ucd/UnicodeData.txt挖出,这是撰写本文时的最新版本(2016年末)(警告:1.5MB文本文件)。阅读起来有点棘手(文档在UAX#44中)。我将首先显示 数字的字符的条目,U + 3023 HANGZHOU NUMERAL THREE(

3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;

第八个以分号分隔的字段是“数值”属性;在这种情况下,其值为3,与字符的名称一致。当且仅当此字段为非空时,Python的str.isnumeric才为真。可以使用unicodedata.numeric直接查询。

第三个​​以分号分隔的字段是一个双字符代码,给出“general category”;在这种情况下,“Nl”。大多数(但不是全部)具有数值的字符都属于“数字”类别之一(类别代码的第一个字母是N)。所有汉族都有例外情况,根据具体情况,可能会或可能不会表示数字;见UAX#38

现在,您要问的字符是:

2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L ;;;;;N;;;    ;2184;
2184;LATIN SMALL LETTER REVERSED C     ;Ll;0;L ;;;;;N;;;2183;    ;2183
218A;TURNED DIGIT TWO                  ;So;0;ON;;;;;N;;;    ;    ;
218B;TURNED DIGIT THREE                ;So;0;ON;;;;;N;;;    ;    ;

这些字符 not 没有分配数值,因此Python的行为是正确的 - 记录在案。

注意:根据https://docs.python.org/3.6/whatsnew/3.6.html,Python将仅在3.6版本中更新为Unicode 9.0.0;但是,AFAICT这些角色在相当长的一段时间内没有改变。

(“为什么这些字符不具有数字值?”是一个只有Unicode联盟才能明确回答的问题;如果您有兴趣,我建议将其提交到mailing lists之一。)< / p>