问题描述
我使用 PDFPlumber 库提取 PDF 中的所有行,提取的示例行如下所示:
总回程运输 16.01 美元
目标是将所有这些放入一个数据框中。如何使用正则表达式对这一行进行分组,以便我可以隔离费用类型和金额?
目前,我有:
totals=re.compile(r"(\ATotal) ([\w]+) ([\w]*)")
for line in text.split("\n"):
line2=totals.search(line)
if line2:
print(line)
print(line2.group(1))
else:
pass
第 1 组返回“总计”,第 2 组返回“返回”,第 3 组返回“运输”,但我无法创建一个检索美元金额的组。有什么建议吗?
注意:超过 1000 美元的美元金额包含一个“,”,可能需要包含在正则表达式语法中
解决方法
只需像这样更改您的正则表达式:
totals=re.compile(r"(\ATotal) ([\w]+) ([\w]*) ([\$ ]+?(\d+([,\.\d]+)?))")
>>> totals.search("Total Return Transportation $16.01").group(4)
'$16.01'
>>> totals.search("Total Return Transportation $1,006.01").group(4)
'$1,006.01'
,
您可以使用具有 4 个捕获组的模式。
请注意,您可以将 [\w]
写成 \w
。
使用 \w*
匹配可选的单词字符,也可能匹配空字符串。
您可以匹配单词字符 1+ 次,并使用匹配左侧 1-3 位数字和逗号的可选部分以及中间 3 位数字的美元金额模式。
\A(Total) (\w+) (\w+) (\$\d{1,3}(?:,\d{3})*(?:\.\d+)?)(?!\S)
-
\A
字符串开头 -
(Total)
捕获第 1 组中的总数并匹配一个空格 -
(\w+)
在第 2 组中捕获 1+ 个单词字符并匹配一个空格 -
(\w+)
在第 3 组中捕获 1+ 个单词字符并匹配一个空格 -
(
捕获第 4 组-
\$\d{1,3}
匹配$
和 1-3 位数字 -
(?:,\d{3})*(?:\.\d+)?
可选择重复 3 位数字并可选择匹配.
和 1+ 位数字
-
-
)
关闭第 4 组 -
(?!\S)
断言右侧的空白边界以防止部分匹配
看到一个 regex demo 和一个 Python demo。
import re
strings = [
"Total Return Transportation $16.01","Total Return Transportation $123,899,116.01","Total Return Transportation $1612.01"
]
pattern = r"\A(Total) (\w+) (\w+) (\$\d{1,\d{3})*(?:\.\d+)?)(?!\S)"
for s in strings:
match = re.match(pattern,s)
if match:
print(match.group(4))
输出
$16.01
$123,116.01