我正在一个项目中,我必须阅读财务报表的扫描图像。我使用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?
我刚刚被介绍给正则表达式,并且正在努力正确地理解语法和文档。我现在正在尝试使用备忘单,但是我很难确定如何解决此问题,请帮忙。
答案 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)
我通过观察您的第一个预期输出编写了此正则表达式。但是我不确定你的第三句话是什么。
([A-Za-z ]+)(?=\d|\S)
匹配名称,直到找到一个数字或符号。.*?
表示我们不在乎的字符串([\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]
表示查找从A
到Z
的所有字母,而[0-9,]
表示查找从0
到9
的数字,以及字符,
。 -
是在方括号内使用的运算符,表示我们想要的一系列字符。+
运算符的意思是查找至少一个出现的对象。例如,表达式[A-Z]+
的意思是查找字母A
至Z
中的至少一个字母。您还可以改用*
运算符,查找出现在其前的元素的至少 个。([A-Z+])
的意思是查找字母A
到Z
中的至少一个字母,然后保存结果。。在将正则表达式匹配的结果分配给变量x.groups()
之后,我们通过执行x
来访问它。 [[TEXT], [NUMBER], [NUMBER]]
。方括号用\
字符转义,因为我们要按字面意义解释它们,而不是将其解释为一系列字符。re.match()
函数将在rev_str
中搜索给定模式匹配的任何位置,并跟踪该匹配范围内的 groups ,并在您致电x.groups()
时返回这些组。这是一个非常简单的示例,但是您必须从某个地方开始,对吧?您应该可以以此为起点,制作更复杂的regex表达式来处理更多代码。