Python:如何通用解析各地区用户习惯格式的数字?
问题
需要解析符合特定地区格式的数字并支持所有地区,原本使用locale.atof方案可行:
from locale import setlocale, LC_NUMERIC, atof setlocale(LC_NUMERIC, ('en_US', 'utf-8')) print(atof("1,234.56")) # 输出为1234.56
但在捷克地区(cs_CZ)无法正常工作:
from locale import setlocale, LC_NUMERIC, atof setlocale(LC_NUMERIC, ('cs_CZ', 'utf-8')) print(atof("1 234,56")) # 抛出ValueError:无法将字符串转为浮点数
原因是捷克地区标准千位分隔符为窄不换行空格(U+202F),仅当输入为"1\u202f234,56"时atof才能正常解析,但用户实际更常输入普通空格(0x20)。直接替换或移除空格仅适用于捷克地区,无法通用。需要一种更宽松的atof替代方法,能解析各地区用户习惯输入的数字格式并转为浮点数,且方案需通用而非仅针对特定地区。
解决方案
可以基于locale模块实现一个通用的灵活解析函数,核心思路是根据当前地区的数字格式规则,自动兼容用户习惯输入的千位分隔符变体:
import locale import re from locale import setlocale, LC_NUMERIC, atof def flexible_atof(num_str): # 获取当前地区的数字格式配置 conv = locale.localeconv() thousands_sep = conv['thousands_sep'] decimal_point = conv['decimal_point'] # 如果当前地区的千位分隔符是空白类字符,将输入中所有空白替换为标准分隔符 if thousands_sep.isspace(): num_str = re.sub(r'\s', thousands_sep, num_str) # 调用标准locale.atof解析处理后的字符串 return atof(num_str)
测试示例
捷克地区(cs_CZ)
setlocale(LC_NUMERIC, ('cs_CZ', 'utf-8')) print(flexible_atof("1 234,56")) # 输出:1234.56 print(flexible_atof("1\u202f234,56")) # 输出:1234.56
美国地区(en_US)
setlocale(LC_NUMERIC, ('en_US', 'utf-8')) print(flexible_atof("1,234.56")) # 输出:1234.56 # 注:en_US地区标准千位分隔符为逗号,输入空格不符合格式会抛出ValueError,符合地区使用习惯
原理说明
- 通过
locale.localeconv()获取当前地区的标准千位分隔符和小数分隔符 - 针对使用空白类字符作为千位分隔符的地区(如捷克、法国等),用正则表达式将输入中所有空白字符(普通空格、窄不换行空格等)统一替换为标准分隔符
- 最后调用标准的
locale.atof解析处理后的字符串,保证对标准格式的兼容性
内容的提问来源于stack exchange,提问作者eNca
相关产品推荐
相关产品推荐

