我只是一个学习Python for ML的初学者。我正在自学NLP,我有一个问题。我有一个csv文件与光学字符识别阅读收据(100个观察值)...one收据每个单元。一个回执的例子如下( csv中的信息以这种方式读取):
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’之前)
我是这样开始的:
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’
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它再次成为一个问题。
我做错了什么?我该如何解决这个问题呢?我想到了遍历文本:
for sentence in text:
(再说一次,然后使用what...how来达到我想要的行数)
任何帮助都将不胜感激。
发布于 2021-10-16 23:08:21
您可以使用正则表达式
(?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的子串:
"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
包含小计:
9
捕获组total
包含总数:
80.45
该问题并未指明产品的位置。假设它可以在小计和合计之前或之后。正是由于这个原因,我在字符串开始锚点^
之后的正前视中捕获了它们。该先行查询不会将引擎的内部字符串指针移到字符串开头之外,从而确保找到小计和总计(如果存在)。
正则表达式执行以下操作。
(?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
我对上面的空格进行了转义,使它们更容易被看到。
https://stackoverflow.com/questions/69599684
复制相似问题