如何从扫描收据生成的文本字符串中提取数据?
扫描收据文本的数据提取方案
嘿,刚好之前做过类似的收据数据提取需求,给你分享几个实用的方案,从简单到复杂都有:
一、先做基础文本清洗(预处理)
扫描转出来的文本大概率会有乱码、多余空格或者换行错位的问题,先做一步预处理能省很多麻烦:
- 把连续多个空格替换成单个,规整文本排版;
- 对齐菜品名称和对应金额的位置(像你示例里菜品和金额是按顺序一一对应的,先把这两行的内容匹配好);
- 统一日期、时间的格式,比如把「2013年1月19日」转成标准的
YYYY-MM-DD格式,方便后续提取识别。
二、基于正则表达式的规则提取(适合固定格式的收据)
如果你的收据格式比较统一(比如这家George's的排版基本不变),用正则是成本最低、见效最快的方法:
- 提取餐厅基础信息:用正则匹配开头的餐厅名、地址、电话,示例正则:
可以分别提取出餐厅名、街道地址、城市区域、邮编、联系电话。^(.+?)\s+(\d+\s+\w+ Street)\s+(\w+\s+\w+)\s+(\w+\s+\d+)\s+(\d{3}-\d{3}-\d{4}) - 提取订单元数据:针对服务员、日期、桌号这些信息,用正则匹配关键词后的内容:
服务员:(.+?)\s+(\d+年\d+月\d+日)\s+桌号(\d+/\d+)\s+晚上(\d+:\d+)\s+客人:(\d+)\s+单号(\d+) - 提取菜品与对应金额:观察到菜品和金额是按顺序排列的,先提取所有非数字的菜品名称,再提取所有
\d+\.\d+格式的金额,然后按位置一一配对即可。 - 提取汇总金额:匹配「小计」「税费」「总计」这些关键词后的数字:
小计\s+税费\s+(\d+\.\d+)\s+(\d+\.\d+)\s+总计\s+(\d+\.\d+)\s+应付余额(\d+\.\d+)
三、OCR+结构化解析工具(适合格式多变或带手写内容的收据)
如果扫描的收据格式不固定,甚至有手写内容,先要用OCR工具把图片转成清晰的文本,再用专门的收据解析库处理:
- 比如用Python的
pytesseract做OCR转文本,再搭配invoice2data库——这个库可以通过自定义模板来匹配提取结构化数据,你可以针对George's的收据格式写一个yaml模板,定义好要提取的字段规则。 - 简单示例代码:
模板里可以明确指定“单号”“总计”等关键词的匹配规则,非常灵活。from invoice2data import extract_data from invoice2data.extract.loader import read_templates # 加载你自定义的收据模板 custom_templates = read_templates('/path/to/your/george_template.yaml') # 从扫描件图片提取数据 receipt_data = extract_data('/path/to/your/receipt_scan.jpg', templates=custom_templates) print(receipt_data)
四、预训练NLP模型(适合大量多样化收据)
如果需要处理很多不同格式的收据,规则和模板不够用,可以用预训练的信息抽取模型:
- 比如基于BERT的预训练模型,针对收据场景做微调,定义好要提取的实体类型:餐厅名、地址、菜品、金额、日期、单号等;
- 也可以直接用Hugging Face上现成的文档抽取模型,输入文本就能自动识别并提取结构化实体,不用自己从零训练。
小Tips
- 先收集一批同类型的收据,总结它们的排版规律,优先用正则或模板方案,成本最低见效最快;
- 扫描的时候尽量保证图片清晰、光线充足,不然OCR识别出错会直接影响后续的数据提取。
内容的提问来源于stack exchange,提问作者santa
相关产品推荐
相关产品推荐

