如何用Python校验字符串是否符合标准美元格式?
标准美元格式校验的正则修正方案
需求回顾
要校验仅含数字、逗号、点的字符串是否符合标准美元格式:
- 可带可选负号
- 整数部分超过3位时,必须按千分位用逗号分隔
- 小数部分只能是0、1或2位,用点分隔
合规与不合规示例:
- 14964,022.97 → 不合规
- 110506785.37 → 不合规(整数超3位未加千分位)
- 67,186,673.9697,764,643.17 → 不合规
- -263,513.52 → 合规
- 15,331,312.0 → 合规
- 15,331,312 → 合规
当前使用的正则^-?\d{1,3}[,.](\d{3}[,.])*.?\d{0,2}?$存在错误,会将15,331,312.102这类3位小数的字符串误判为合规。
原正则的问题点
- 千分位与小数点混用:
[,.]允许用点作为千分位分隔符,不符合美元格式规范,还会导致整数部分可能以点结尾,干扰小数匹配。 - 强制开头带分隔符:
\d{1,3}[,.]要求1-3位数字后必须跟逗号或点,无法匹配123这类纯3位以内的整数。 - 小数点未转义:
.?中的点是正则通配符(匹配任意字符),不是特指小数点,应该写成\.?。 - 非贪婪匹配导致误判:
\d{0,2}?的非贪婪模式会优先匹配最少位数,使得多余的小数位被忽略,导致3位小数的字符串通过校验。
修正后的正则表达式
^-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?$
正则拆解说明
-?:匹配可选的负号\d{1,3}(?:,\d{3})*:整数部分规则,1-3位数字开头,后续可重复“逗号+3位数字”的组合,确保千分位格式正确(?:\.\d{1,2})?:可选的小数部分,必须以点开头,后跟1或2位数字;无小数时该部分匹配空
代码实现与测试
import re def is_valid_usd(amount_str): usd_pattern = r'^-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?$' return bool(re.fullmatch(usd_pattern, amount_str)) # 测试用例验证 test_samples = [ ("14964,022.97", False), ("110506785.37", False), ("67,186,673.9697,764,643.17", False), ("-263,513.52", True), ("15,331,312.0", True), ("15,331,312", True), ("15,331,312.102", False), ("123", True), ("-12,345.6", True), ("123.456", False) ] for s, expected in test_samples: result = is_valid_usd(s) print(f"{s}: {'yes' if result else 'no'} (预期: {'yes' if expected else 'no'})")
运行上述代码后,所有测试用例都会得到符合预期的结果,包括15,331,312.102会被正确判定为不合规。
内容的提问来源于stack exchange,提问作者haojie
相关产品推荐
相关产品推荐

