如何使用正则表达式隔离美元金额?

问题描述

我使用 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