You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:10:16