如何在Python中计算包含unicode组件的字符串的数值?
根据我之前的问题,如何在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……不过如果有多个小数点的话就不行了。