繁体   English   中英

Python:在正则表达式匹配之间提取多行

[英]Python: Extracting multiple lines between RegEx Matches

晚上好,

我正在使用 python 将 PDF 转换为 CSV 并使用 RegEx 提取信息。

从 PDF 提取文本后,原始文本可能如下所示:

Account Transaction Details
Twin Account   123-456-789-1
Date Description Withdrawals Deposits Balance
01 Jan BALANCE B/F 123,456.78  
03 Jan Funds Transfer 195.04 123,456.78  
mBK-4653112690
03 Jan Inward Credit-QUICK 3,000.84 123,456.78  
WIRE OTHR
ANTON HARLEY
Other
03 Jan Funds Trf - SPEED 3,500.00 123,345.78  
PIB8452145632845963
Abricot 480
OTHR Transfer

我使用了 RegEx [0-3]{1}[0-9]{1}\s[AZ]{1}[az]{2}\s[?A-Za-z]{1,155}并设法获取所需的交易:

01 Jan BALANCE B/F 123,456.78
03 Jan Funds Transfer 195.04 123,456.78
03 Jan Inward Credit-QUICK 3,000.84 123,456.78
03 Jan Funds Trf - SPEED 3,500.00 123,345.78

但是,匹配之间的附加信息已被删除,因为我已使用\n拆分文本,然后运行 RegEx。

如何进行编码,以便获得 RegEx 匹配之间的附加信息,并将附加信息标记到上一个匹配? 这是我设想的 output:

01 Jan BALANCE B/F 123,456.78
03 Jan Funds Transfer 195.04 123,456.78 mBK-4653112690
03 Jan Inward Credit-QUICK 3,000.84 123,456.78 OTHR ANTON HARLEY Other
03 Jan Funds Trf - SPEED 3,500.00 123,345.78 PIB8452145632845963 Abricot 480 OTHR Transfer

编辑:

我已经适应了@dcsuka 解决方案并获得了以下信息:

06 Jan Debit-Consumer 12.60 123,456.78   SNIP AVENU13568100 4265884035605848

06 Jan Inward DR - 828.24 123,456.78   SHIP G12345HUJ ITX

07 Jan Funds Transfer 50.00 123,456.78   Pleasenotethatyouareboundbyadutyundertherulesgoverningtheoperationofthisaccount,tochecktheentriesintheabovestatement. Ifyoudonotnotifyusinwritingofanyerrors, omissionsorunauthoriseddebitswithinfourteen(14)daysofthisstatement,theentriesaboveshallbedeemedvalid,correct,accurateandconclusivelybindinguponyou,andyoushallhaveno claim against the bank in relation thereto. XYZ Ltd  •  80 QuincyPlace ABC Plaza XXX 12345  •  Co. Reg. No. 1234567890Z  •  GST Reg. No. YY-8121234-2  •   www.xyzabc.com

07 Jan Inward CR - SPEED 9,092.06 123,456.78   SALAD SALAS Payment CARL QWE 817264950

如何删除多余的单词“ Pleasenotethatyouareboundbyadut... ” 我能看到的唯一模式是它会是一个很长的单词(可能超过 20 个字符)。 那是通往 go 的路吗?

编辑2:

@dcsuka 已根据单词或超过 20 个字符调整代码以帮助消除“噪音”。 谢谢dcsuka!

您可以尝试在拆分字符串时对换行符后的数字使用正向前瞻,以获得更大的块,更能反映您预期的 output:

import re

split_text = re.split("\n(?=\d{1,3}\s)", text1)

[" ".join(i.split()) for i in split_text if re.search("^\d\d\s", i)]

# ['01 Jan BALANCE B/F 123,456.78',
#  '03 Jan Funds Transfer 195.04 123,456.78 mBK-4653112690',
#  '03 Jan Inward Credit-QUICK 3,000.84 123,456.78 WIRE OTHR ANTON HARLEY Other',
#  '03 Jan Funds Trf - SPEED 3,500.00 123,345.78 PIB8452145632845963 Abricot 480 OTHR Transfer']

在我获得更多关于正则表达式的知识后,我试图再次查看它。

就像@dcsuka 建议的那样,我需要使用积极的前瞻(这样我的正则表达式就不会消耗我最后设置的“量词”)

这是我使用的代码:

(^[0-9]{2}) ([A-Z]{1}[a-z]{2}) (.*?)(?=\n[0-9]{2} [A-Z]{1}[a-z]{2}|[A-Za-z]{15,})', flags=re.M | re.S

首先,我将它们分为:

  1. 使用(^[0-9]{2})的日期,使用 '^' 表示行首,因为日期为 2 位数字(01 或 11)
  2. 使用([AZ]{1}[az]{2})的月份,因为月份是 12 月/ 1 月/ 2 月...
  3. 我想要使用(.*?)的主要捕获,在这种情况下是描述
  4. 日期和月份,其他描述使用(?=\n[0-9]{2} [AZ]{1}[az]{2}|[A-Za-z]{15,})
  5. 最后,我将标志用于多行和单行flags=re.M | re.S flags=re.M | re.S ,以便多行合并为一行供我的正则表达式搜索。

完成后,我使用re.findall(line_re)搜索所有匹配项。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM