Flutter中基于google_ml_kit的收据关键信息提取方案咨询
收据关键信息提取:Regex与规则式标注方案
针对你用google_ml_kit提取收据文本后,要提取公司名称、手机号、地址、邮箱、总金额的需求,下面是可落地的文本标注方法,重点讲Regex实现和辅助规则:
一、Regex模式实现(按字段分类)
Regex是快速匹配结构化信息的首选,针对不同字段的通用匹配规则如下:
1. 手机号码
适配多数地区的号码格式(支持国际区号、分隔符):
^(\+?\d{1,3}[-.\s]?)?\d{10,15}$
如果是国内收据,可简化为更精准的规则:
^1[3-9]\d{9}$
2. 邮箱地址
标准通用邮箱格式匹配:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
3. 总金额
适配带货币符号、千分位、小数的金额格式:
(总计|Total|Amount Due)\s*(\D?(\d{1,3}(,\d{3})*|\d+)(\.\d{2})?)
如果收据没有“总计”这类关键词,可直接匹配纯金额格式:
^\D?(\d{1,3}(,\d{3})*|\d+)(\.\d{2})?$
4. 公司名称
纯Regex难以覆盖所有格式,结合关键词+位置匹配:
- 匹配含公司后缀的文本:
.*(有限公司|Inc\.|Corp\.|Ltd\.|股份公司|集团).*
- 结合
google_ml_kit返回的文本块坐标,优先取顶部(y坐标最小)的文本块,因为公司名通常在收据抬头位置。
5. 地址
同样结合关键词+上下文:
- 匹配带地址标识的文本:
(地址|Add:|Address:|住址)\s*(.*)
- 提取该文本块后续的1-3行内容,因为地址通常是多行连续的;也可匹配含街道、邮编、城市关键词的行:
.*(\d+号|街道|Street|Road|City|邮编|Zip).*
二、Dart代码示例(适配google_ml_kit)
假设你已经通过google_ml_kit提取了文本行列表List<String> receiptLines,以下是字段提取的实现:
提取邮箱
RegExp emailRegex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'); String? extractEmail(List<String> lines) { for (var line in lines) { final trimmedLine = line.trim(); if (emailRegex.hasMatch(trimmedLine)) { return trimmedLine; } } return null; }
提取手机号
RegExp phoneRegex = RegExp(r'^(\+?\d{1,3}[-.\s]?)?\d{10,15}$'); String? extractPhone(List<String> lines) { for (var line in lines) { final trimmedLine = line.trim(); final matches = phoneRegex.allMatches(trimmedLine); if (matches.isNotEmpty) { return matches.first.group(0); } } return null; }
提取总金额
String? extractTotalAmount(List<String> lines) { // 先匹配带关键词的金额 RegExp totalKeywordRegex = RegExp(r'(总计|Total|Amount Due)\s*(\D?(\d{1,3}(,\d{3})*|\d+)(\.\d{2})?)', caseSensitive: false); for (var line in lines) { final trimmedLine = line.trim(); final matches = totalKeywordRegex.allMatches(trimmedLine); if (matches.isNotEmpty) { return matches.first.group(2); } } // 无关键词则从底部匹配纯金额 RegExp amountRegex = RegExp(r'^\D?(\d{1,3}(,\d{3})*|\d+)(\.\d{2})?$'); for (var line in lines.reversed) { final trimmedLine = line.trim(); if (amountRegex.hasMatch(trimmedLine)) { return trimmedLine; } } return null; }
三、优化方案(针对复杂收据)
如果收据格式差异大,Regex匹配准确率不足,可结合google_ml_kit的文本块位置信息:
- 公司名:筛选y坐标最小的前2个文本块,检查是否含公司后缀关键词;
- 地址:找到带“地址”关键词的文本块后,提取其下方相邻的2-3个文本块合并为地址;
- 总金额:优先取y坐标较大的文本块(收据底部),匹配金额格式。
如果需要更高准确率,可考虑训练轻量的命名实体识别(NER)模型,但Regex是最快落地、成本最低的方案。
内容的提问来源于stack exchange,提问作者Mou Rani Biswas
相关产品推荐
相关产品推荐

