Python实现OCR识别非标准数值的格式化转换
嘿,这是个挺典型的OCR数值清洗需求啊!我之前做文档自动化的时候也碰到过类似的问题,分享几个更简洁高效的优化思路和实现方案给你参考:
优化思路拆解
核心是把杂乱的OCR输出拆解成「清洗→解析→校验」三个步骤,每个步骤聚焦单一任务:
- 无效字符过滤:先把OCR混入的随机杂字符(比如字母、多余符号)清掉,只保留数字、小数点、斜杠和分隔整数与分数的空格
- 多格式兼容解析:统一处理带空格的分数、错误格式分数、缺项分数和纯浮点数,转换成标准数值
- 数值校验截断:确保最终结果不超过11,避免异常值
具体实现(Python示例)
这个方案能覆盖你提到的所有场景,还加了除零保护、异常格式兼容的细节:
import re def normalize_ocr_numeric(input_str): # 第一步:过滤无效字符,保留数字、.、/、空格和负号(可选) cleaned = re.sub(r'[^0-9./\s-]', '', input_str.strip()) # 处理OCR常见错误:把逗号替换成小数点(如果有需要) cleaned = cleaned.replace(',', '.') # 第二步:解析分数或浮点数 if '/' in cleaned: # 拆分整数、分子、分母部分,过滤空字符串 parts = [p for p in re.split(r'[\s/]', cleaned) if p] integer_part = 0.0 numerator = 0.0 denominator = 1.0 # 适配不同分数格式 if len(parts) == 1: # 比如输入'T 3/',只剩分子,默认分母为1 numerator = float(parts[0]) elif len(parts) == 2: # 纯分数格式,比如'3/4'或'4.75/2' numerator = float(parts[0]) denominator = float(parts[1]) if parts[1] != '' else 1.0 else: # 整数+分数格式,比如'4 3/4'或'4 .3/4' integer_part = float(parts[0]) numerator = float(parts[1]) denominator = float(parts[2]) if parts[2] != '' else 1.0 # 避免除零错误 denominator = denominator if denominator != 0 else 1.0 value = integer_part + (numerator / denominator) else: # 处理纯浮点数/整数,空输入默认返回0 value = float(cleaned) if cleaned else 0.0 # 第三步:限制数值不超过11 value = min(value, 11.0) # 可选:保留指定小数位数,比如两位 # value = round(value, 2) return value # 测试用例验证 test_cases = [ '4 3/4', '4 .3/4', '4.75', 'T 3/', '12 1/2', 'abc5/2', '7.', '/8', '-1 1/2' ] for case in test_cases: print(f"输入: '{case}' → 输出: {normalize_ocr_numeric(case)}")
额外优化建议
- 如果OCR经常出现重复数字、多打符号的情况,可以在预处理阶段加去重逻辑(比如把'44 3/4'里的重复4处理成单个)
- 可以加日志记录异常输入(比如完全无法解析的字符串),方便后续迭代优化规则
- 对性能要求极高的场景,可以用字符串遍历代替正则,但正则已经能覆盖90%以上的日常需求
内容的提问来源于stack exchange,提问作者FanScience
相关产品推荐
相关产品推荐

