使用REGEX阅读财务报表

时间:2018-12-07 04:48:35

标签: python regex python-3.x

我正在一个项目中,我必须阅读财务报表的扫描图像。我使用tesseract 4将图像转换为文本输出,如下所示(这是一个片段):

收入9,000,000 900,000

销售成本900,000 900,000

毛利润(90%; 2016-90%)900,000 900,000

我想将以上内容分解为三个条目的列表,其中第一个条目为文本,然后第二个和第三个条目为数字。例如,第一行看起来像这样:

[[REVENUE], [9,000,000], [9,000,000]]

我碰到了这个堆栈溢出的帖子,有人试图对re.match()方法使用.groups()来查找模式:How to split strings into text and number?

我刚刚被介绍给正则表达式,并且正在努力正确地理解语法和文档。我现在正在尝试使用备忘单,但是我很难确定如何解决此问题,请帮忙。

3 个答案:

答案 0 :(得分:1)

正像您所说的那样,正则表达式对于解决此问题是过大的。

text.split()和前两个项目中的join个更适合于此。

lines = [ "REVENUE 9,000,000 900,000",
          "COST OF SALES 900,000 900,000",
          "GROSS PROFIT (90%; 2016 - 90%) 900,000 900,000" ]
out = []
for line in lines:
    parts = line.split()
    if len(parts) < 3:
        raise InputError
    if len(parts) == 3:
        out.append(parts)
    else:
        out.append([' '.join(parts[0:len(parts)-2]), parts[-2], parts[-1]])

out将包含

 [['REVENUE', '9,000,000', '900,000'], 
  ['COST OF SALES', '900,000', '900,000'], 
  ['GROSS PROFIT (90%; 2016 - 90%)', '900,000', '900,000']]

如果标签文本需要进一步提取,则可以使用正则表达式,也可以只查看parts[0:len(parts)-2]中的项目并根据其中的单词和数字对其进行处理。

答案 1 :(得分:1)

我通过观察您的第一个预期输出编写了此正则表达式。但是我不确定你的第三句话是什么。

  1. ([A-Za-z ]+)(?=\d|\S)匹配名称,直到找到一个数字或符号。
  2. .*?表示我们不在乎的字符串
  3. ([\d,]+)\s([\d,]+|(?=-\n|-$))匹配一组或两组数字,如果只有一组数字,则该组应以换行符或文本结尾。

测试代码(已编辑):

import re

regex = r"([A-Za-z ]+)(?=\d|\S).*?([\d,]+)\s([\d,]+|(?=-\n|-$))"

text = """
REVENUE 9,000,000 900,000

COST OF SALES 900,000 900,000

GROSS PROFIT (90%; 2016 - 90%) 900,000 900,000

Business taxes 999 -
"""

print(re.findall(regex,text))
# [('REVENUE ', '9,000,000', '900,000'), ('COST OF SALES ', '900,000', '900,000'), ('GROSS PROFIT ', '900,000', '900,000'), ('Business taxes ', '999', '')]

答案 2 :(得分:0)

检测字符串

rev_str = "[[REVENUE], [9,000,000], [9,000,000]]"

并提取值

("REVENUE", "9,000,000", "9,000,000")

你会做

import re
x = re.match(r"\[\[([A-Z]+)\], \[([0-9,]+)\], \[([0-9,]+)\]\]", rev_str)
x.groups()
# ('REVENUE', '9,000,000', '9,000,000')

让我们解开这个大字符串。

  • 方括号表示字符范围。例如,[A-Z]表示查找从AZ的所有字母,而[0-9,]表示查找从09的数字,以及字符,-是在方括号内使用的运算符,表示我们想要的一系列字符。
  • +运算符的意思是查找至少一个出现的对象。例如,表达式[A-Z]+的意思是查找字母AZ中的至少一个字母。您还可以改用*运算符,查找出现在其前的元素的至少 个。
  • 圆括号(即括号)表示要从正则表达式中提取的 group 。只要该模式匹配,括号中任何表达式内的内容都会被提取并作为一个组返回。例如,([A-Z+])的意思是查找字母AZ中的至少一个字母,然后保存结果。。在将正则表达式匹配的结果分配给变量x.groups()之后,我们通过执行x来访问它。
  • 否则,这很简单-容纳模式[[TEXT], [NUMBER], [NUMBER]]。方括号用\字符转义,因为我们要按字面意义解释它们,而不是将其解释为一系列字符。
  • 总体而言,re.match()函数将在rev_str中搜索给定模式匹配的任何位置,并跟踪该匹配范围内的 groups ,并在您致电x.groups()时返回这些组。

这是一个非常简单的示例,但是您必须从某个地方开始,对吧?您应该可以以此为起点,制作更复杂的regex表达式来处理更多代码。