首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从收款机收据的Google OCR转储文本csv文件中提取特定数据

如何从收款机收据的Google OCR转储文本csv文件中提取特定数据
EN

Stack Overflow用户
提问于 2021-10-16 21:30:04
回答 1查看 64关注 0票数 0

我只是一个学习Python for ML的初学者。我正在自学NLP,我有一个问题。我有一个csv文件与光学字符识别阅读收据(100个观察值)...one收据每个单元。一个回执的例子如下( csv中的信息以这种方式读取):

代码语言:javascript
运行
复制
text = '''ㅎㅎ
Fresh Food
The fresh food people
5619 Lorem PH: 00 0000 0000
204 Some Road
TAX INVOICE - ABN 88 000 014 675
Gift Card Visa Varbl 20to500Dollars
Potato White Washed 2Kg
Nescafe Coffee Blend 43 50g
^HToblerone Milk Chocolate Bar 50g
^HOreo Cookie Original 133g
#M&Ms Crispy 145g
*HRed Rock Deli Portgse Chicken 150g
^HWrigleys Extra Pepprmint 14pc 27g
Qty
57.95
3.50
5.00
0.90
1.50
4.50
3.50
2 @ $1.80
each
3.60
$80.45
9 SUBTOTAL
TOTAL
$80.45
REWARDS SAVINGS
$10.00
Fresh Food
5619
Lorem'''

然而,收据通常是非结构化的(即,有些项目比其他项目具有更多的行和附属信息)在布局中有3个内容非常结构化,我正在尝试提取这些信息:小计金额(总是出现在合计之前),总金额(总是出现在小计之后),以及购买的商品列表(总是出现在ABN数字之后,结束于‘Qty’之前)

我是这样开始的:

代码语言:javascript
运行
复制
re.split(r'\s+', text) --->splits the string into a list of words

‘®…Ž?Â…Ž‘,'Freah',’食品‘,'The','fresh','food','people','5619','Unley','PH:','00','0000','0000','204',’一些‘,’路‘,’税‘,’发票‘,'-','ABN','88','000','014','675',’礼物‘,’卡‘,‘'Visa','Varbl',’20to500美元‘,’土豆‘,’白‘,’洗净‘,’2 2Kg‘,'Nescafe','Coffee','Blend','43','50g','^HToblerone','Milk','Chocolate','Bar','50g','^HOreo','Cookie','Original','133g','#M&Ms','Crispy','145g','*HRed',‘摇滚’,‘熟食店’,'Portgse',‘鸡肉’,'150g','^HWrigleys','Extra','Pepprmint','14pc','27g','Qty','57.95','3.50','5.00','0.90','1.50','4.50','3.50','2','@','$1.80','each','3.60','$80.45','9','SUBTOTAL','TOTAL','$80.45',‘奖励’,‘储蓄’,'$10.00',‘新鲜’,‘食品’,'5619','UNLEY','SA','TCDM','ID.',‘谢谢’,‘您’,'tor',‘购物’,‘有’,‘我们’,‘商店’,'5619',‘'POS','065','TRANS','8660','13:39','04/08/2021’

代码语言:javascript
运行
复制
x = re.search('SUBTOTAL', text)
print(x.group())
y = re.search('TOTAL', text)
print(y.group())

小计

合计

现在我试图获得小计前的数字(9)和总数($80.45)后的数量...I尝试循环通过文本列表和尝试正则表达式,但我不能得到我的want....Also,我被难住了,我如何才能提取项目购买(字符串之间的文本‘荷兰银行88 000 014675’和‘数量’,虽然拆分已拆分的ABN和数字作为不同的词,因为well...so它再次成为一个问题。

我做错了什么?我该如何解决这个问题呢?我想到了遍历文本:

代码语言:javascript
运行
复制
for sentence in text:

(再说一次,然后使用what...how来达到我想要的行数)

任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-16 23:08:21

您可以使用正则表达式

代码语言:javascript
运行
复制
(?s)^(?=.* ABN \d{2}(?: \d{3}){3}\n(?P<products>.*\n)Qty\n).*\n\$(?P<subtotal>\d+\.\d{2})\n\d+ SUBTOTAL\.*\nTOTAL\n\$(?P<total>\d+\.\d{2})\n

捕获组products包含products的子串:

代码语言:javascript
运行
复制
"Gift Card Visa Varbl 20to500Dollars\nPotato White Washed 2Kg\nNescafe Coffee Blend 43 50\n^HToblerone Milk Chocolate Bar 50g\n^HOreo Cookie Original 133\n#M&Ms Crispy 145g\n*HRed Rock Deli Portgse Chicken 150g\n^HWrigleys Extra Pepprmint 14pc 27g(?.*\nz"

如果需要,可以在换行符上使用夹板。

捕获组subtotal包含小计:

代码语言:javascript
运行
复制
9

捕获组total包含总数:

代码语言:javascript
运行
复制
80.45

Demo

该问题并未指明产品的位置。假设它可以在小计和合计之前或之后。正是由于这个原因,我在字符串开始锚点^之后的正前视中捕获了它们。该先行查询不会将引擎的内部字符串指针移到字符串开头之外,从而确保找到小计和总计(如果存在)。

正则表达式执行以下操作。

代码语言:javascript
运行
复制
(?s)             # cause periods to match all chars, including newlines
^                # match beginning of string
(?=              # begin positive lookahead
  .*             # match zero or more chars
  \ ABN\         # match ' ABN '
  \d{2}          # match 2 digits
  (?:            # begin a non-capture group
    \ \d{3}      # match a space followed by 3 digits
  ){3}           # end non-capture group, execute thrice 
  \n             # match newline
  (?P<products>  # begin a capture group named 'products'
    .*           # match zero or more chars including newlines           
    \n           # match newline
  )              # end capture group
  Qty\n          # match 'Qty', newline
)                # end positive lookahead
.*\n             # match zero or more chars, newline
\$\d+\.\d{2}\n   # match '$', one or more digits, period, 2 digits, newline
(?P<subtotal>    # begin capture group named 'subtotal'
  \d+            # match one or more digits
)                # end capture group
\ +SUBTOTAL\n    # match one or more spaces, 'SUBTOTAL', newline
TOTAL\n          # match 'TOTAL', newline
\$               # match '$'
(?P<total>       # begin capture group named 'total'       
  \d+\.\d{2}     # match one or more digits, period, 2 digits
)                # end capture group
\n               # match newline

我对上面的空格进行了转义,使它们更容易被看到。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69599684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档