Чтение финансовой отчетности с использованием REGEX

1

Я работаю над проектом, где мне приходится читать отсканированные изображения финансовых отчетов. Я использовал 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() где кто-то пытается использовать re.match() для .groups() чтобы найти шаблон: как разбить строки на текст и число?

Я просто знаком с регулярным выражением, и я стараюсь правильно понять синтаксис и документацию. На данный момент я пытаюсь использовать чит-лист, но мне сложно определить, как это сделать, пожалуйста, помогите.

Теги:
python-3.x

3 ответа

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', '')]
  • 0
    Как мы учитываем отрицательные числа? В финансовых документах они отображаются так: (9 000 000)
  • 0
    Кроме того, для случая, когда что-то отображается следующим образом, как бы вы учли этот случай 'Business taxes 999 - ?» так что в основном я хочу получить следующий результат [[налоги на бизнес], [999], [-]] .... где дефис является пустым числом
Показать ещё 1 комментарий
1

Regexes являются излишними для этой проблемы, как вы заявили об этом.

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] и обработать их на основе слов и цифр.

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')

Пусть распакует эту большую ол-строку.

  • Квадратные скобки означают ряд символов. Например, [AZ] означает искать все буквы от до A Z, в то время как [0-9,] означает искать цифры 0 через 9, а также характер ,. - вот оператор используется внутри квадратные скобки для обозначения диапазона символов, которые мы хотим.
  • Оператор + означает поиск по крайней мере одного события того, что непосредственно предшествует ему. Например, выражение [AZ]+ означает поиск хотя бы одного вхождения любой буквы A в Z Вы также можете использовать оператор *, чтобы искать по крайней мере нулевые вхождения того, что предшествует ему.
  • Круглые скобки (т.е. круглые скобки) означают группу, которую нужно извлечь из регулярного выражения. Всякий раз, когда этот шаблон сопоставляется, все, что находится внутри любого выражения в круглых скобках, будет извлечено и возвращено как группа. Например, ([A-Z+]) означает искать хотя бы одно вхождение любой буквы A Z, а затем сохранять все, что окажется. Мы x.groups() доступ к этому, выполняя x.groups() после присвоения результата соответствия регулярному выражению переменной x.
  • В противном случае это просто - для размещения шаблона [[TEXT], [NUMBER], [NUMBER]]. Квадратные скобки экранируются символом \, потому что мы хотим интерпретировать их буквально, а не как набор символов.
  • В целом re.match() будет искать rev_str для любых мест, где данный шаблон соответствует, отслеживать группы в этом совпадении и возвращать эти группы при вызове x.groups().

Это довольно простой пример, но вы должны что-то начать, верно? Вы должны использовать это как отправную точку для создания более сложного выражения регулярного выражения для обработки большего количества вашего кода.

  • 0
    ... о, это была не та проблема, которую ты пытался решить. Ну да ладно, надеюсь еще полезная информация.
  • 0
    Все еще отличное руководство по обучению, большое спасибо за это!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню