如何在Python中计算包含unicode组件的字符串的数值?

4 投票
4 回答
2461 浏览
提问于 2025-04-15 13:33

根据我之前的问题,如何在Python中将unicode字符转换为浮点数?,我想找到一个更优雅的方法来计算包含unicode数字值的字符串的值。

举个例子,像字符串“1⅕”和“1 ⅕”。我希望它们能计算出1.2这个结果。

我知道可以逐个字符地遍历这个字符串,检查每个字符的类型是否是数字,然后用unicodedata.numeric(x)来转换unicode字符。接着,我还得把字符串分开并把这些值加起来。不过,这样的方法感觉有点笨拙和不稳定。在Python中有没有更优雅的解决方案呢?

4 个回答

0

这段代码可能对你有用,具体要看你想处理的那些奇怪情况:

val = 0
for c in my_unicode_string:
    if unicodedata.category(unichr(c)) == 'No':
        cval = unicodedata.numeric(c)
    elif c.isdigit():
        cval = int(c)
    else:
        continue
    if cval == int(cval):
        val *= 10
    val += cval
print val

这里假设整数部分是数字,分数部分是要加到这个数字上的小数。不过,它对数字之间的空格、重复的小数等情况处理得不好。

1
>>> import unicodedata
>>> b = '10 ⅕'
>>> int(b[:-1]) + unicodedata.numeric(b[-1])
10.2

define convert_dubious_strings(s):
    try:
        return int(s)
    except UnicodeEncodeError:
        return int(b[:-1]) + unicodedata.numeric(b[-1])

如果它可能没有整数部分,那么就需要再加一个try-except的子块。

2

我觉得这就是你想要的...

import unicodedata
def eval_unicode(s):
    #sum all the unicode fractions
    u = sum(map(unicodedata.numeric, filter(lambda x: unicodedata.category(x)=="No",s)))
    #eval the regular digits (with optional dot) as a float, or default to 0
    n = float("".join(filter(lambda x:x.isdigit() or x==".", s)) or 0)
    return n+u

或者对于那些喜欢全面解决方案的人来说,可以看看这个:

import unicodedata
def eval_unicode(s):
    #sum all the unicode fractions
    u = sum(unicodedata.numeric(i) for i in s if unicodedata.category(i)=="No")
    #eval the regular digits (with optional dot) as a float, or default to 0
    n = float("".join(i for i in s if i.isdigit() or i==".") or 0)
    return n+u

不过要注意,有很多unicode字符在python中似乎没有被分配数字值(比如⅜和⅝就不行……或者可能只是我键盘的问题,哈哈)。

关于实现的另一个说明:这个方法“太强大”了,即使是像“123½3 ½”这样的错误数字也能处理,最后会把它算成1234.0……不过如果有多个小数点的话就不行了。

撰写回答