Python里的isnumeric和isdigit方法异同
好久没写东西了,除了确实比较摆的主观原因之外还有要搞那个SMP 2023的复赛的客观原因。那个项目写着感觉也还学到或者说复习了不少东西,包括正则表达式、操作数据库还有用HuggingFace库对生成式模型的生成参数做调整等,这些以后有时间单独写一篇。
今天这篇只谈一个很小的点,就是假设随便给一个字符串,如何判断里面的文本是不是数字呢?
这个方案其实还挺多,最简单的就是直接float
强转一下然后错误处理,出错的肯定就不是数字了。但实际上,Python已经在字符串里给出了很方便的函数来判断是不是数字,但是也比较容易混淆,即isnumeric
和isdigit
方法。
两者的异同
首先先说一下两者的共同点,就是它们对于阿拉伯整数都有很好地判断能力,比如:
1 | a = "12345" |
但是isnumeric
的范围是更广的,它甚至可以识别中文的数字表达:
1 | a = "三百二十一" |
这非常的夸张,如果我们只想要阿拉伯数字构成的文本,用isnumeric
方法之后会把汉字的数字字符也当成数字,在后面要进行转换的时候就可能出问题,所以这种情况下我们应该用isdigit
。
二者不是完备的数字检测方法
那是不是可以这样说呢,如果我们有处理中文表达的数字的能力,我们就可以用isnumeric
把中文数字字符串放进来,反之如果我们只想要阿拉伯数字组成的字符串,就使用isdigit
呢?
遗憾地是,似乎isnumeric
并不能查全中文的数字表达,比如一个很常见的表达”两百“,在该方法中就会返回False,因为该方法似乎并不认为”两“是数字。
1 | a = "两百" |
这会把很多含“两”说法的中文数字拒之门外,因此,isnumeric
方法并不能很完备地识别中文数字的表达,可能需要增加一些额外的规则才能让它变得好用。
那isdigit
呢,在int类型上似乎没啥问题,但同样它不能识别小数。当然这是吹毛求疵的要求,因为在英文中,"digit"通常指的是整数位数,不包括小数。所以如果你想检测一个字符串是不是阿拉伯数字组成的合法小数,那就用float
尝试转换一下就可以了。
但是有实用性
尽管都不能涵盖所有情况,但是如果限制应用场景,这两个方法都能成为相当有用的方法。比如我们定义一个能查找中文和阿拉伯数字的正则表达式:
1 | import re |
现在这个正则表达式能够匹配中文和阿拉伯数字,但离真正转换成int类型还有一段距离。因为由数字1-9组成的字符串只需要用int
转换一下即可,但中文数字还需要进一步处理一下。因此此时isdigit
方法就能充当这个路由的作用。
1 | def str2int(string: str): |
可以实现一个中文转数字的函数:
1 | def chinese_to_number(chinese_str): |
这样两者配合就能实现中文和阿拉伯文数字识别通吃了。
但是这样就完备吗,显然也是不行的,它对错误的表达天然没有抵御能力。比如“三百七千六”,它不会有告警信息而是直接转换为"7306"了,这个很难说是错是对,因为表达就不对。然后第二点是对中文和阿拉伯数字混杂的表达没有处理,比如"3百"这样的表达它也是无能为力的,但是它会报错而不是直接入库,这可以给使用者处理的空间。
小结
总结一下,如果要提取的信息确定是合规的,这些函数配合起来确实是实用的。但不要指望它们能够处理所有的问题。第二点就是对于类似的函数还是要注意一下区别,以防止误用。