Как извлечь конкретную информацию из многострочной строки - PullRequest
2 голосов
/ 08 мая 2019

Я извлек некоторую информацию, связанную со счетами, из тела письма в строки Python, моя следующая задача - извлечь номера строк из строки.Формат электронных писем может варьироваться, поэтому становится трудно найти номер счета из текста.Я также попробовал «Распознавание именованных объектов» из SpaCy, но, поскольку в большинстве случаев номер счета-фактуры указывается в следующей строке из заголовка «Счет-фактура» или «Счет-фактура №», NER не понимает отношения и возвращает неверные данные.

Ниже приведены 2 примера текста, извлеченного из тела письма:

Пример - 1.

Dear Customer:
The past due invoices listed below are still pending. This includes the 
following:

Invoice   Date     Purchase Order  Due Date  Balance
8754321   8/17/17  7200016508      9/16/18   140.72
5245344   11/7/17  4500199620      12/7/18   301.54

We would appreciate quick payment of these invoices.

Пример - 2.

Hi - please confirm the status of below two invoices.

Invoice#               Amount               Invoice Date       Due Date          
7651234                $19,579.06          29-Jan-19           28-Apr-19            
9872341                $47,137.20          27-Feb-19           26-Apr-19 

Моя проблема заключается в том, что если я преобразую весь этот текст в одну строку, то это будет выглядеть примерно так:

Invoice   Date     Purchase Order  Due Date  Balance 8754321   8/17/17 
7200016508     9/16/18   140.72

Как видно, номер счета-фактуры (в данном случае 8754321) изменил свою позицию и не 'больше не следуйте ключевому слову "Счет-фактура", которое сложнее найти.

Мой желаемый вывод выглядит примерно так:

Output Example - 1 - 

8754321
5245344

Output Example - 2 - 

7651234                
9872341        

Я не знаю, как я могу получить текст только под ключевым словом "Invoice" или "Invoice #" это номер счета.

Пожалуйста, дайте мне знать, если потребуется дополнительная информация.Спасибо !!

Редактировать: Номер счета-фактуры не имеет заранее определенной длины, он может быть 7 цифрами или может быть больше этого.

Ответы [ 3 ]

2 голосов
/ 09 мая 2019

Код за мои комментарии.

email = '''Dear Customer:
The past due invoices listed below are still pending. This includes the 
following:

Invoice   Date     Purchase Order  Due Date  Balance
8754321   8/17/17  7200016508      9/16/18   140.72
5245344   11/7/17  4500199620      12/7/18   301.54

We would appreciate quick payment of these invoices.'''

index = -1
# Get first line of table, print line and index of 'Invoice'
for line in email.split('\n'):
    if all(x != x.lower() for x in line.split()) and ('Invoice' in line) and len(line) > 0:
        print('--->', line, ' --- index of Invoice:', line.find('Invoice'))
        index = line.find('Invoice')

Использует эвристический метод, согласно которому строка заголовка столбца всегда указывается регистром или прописными буквами (ID). Это потерпит неудачу, если сказать, что заголовок был точно «Счет №». а не «номер счета»

# get all number at a certain index
for line in email.split('\n'):
     words = line[index:].split()
     if words == []: continue
     word = words[0]
     try:
         print(int(word))
     except:
         continue

Надежность здесь зависит от данных. Таким образом, в моем коде столбец Invoice должен быть первым в заголовке таблицы. то есть, вы не можете иметь «Дата счета» перед «Счетом». Очевидно, что это нужно исправить.

1 голос
/ 08 мая 2019

Использование Regex. re.findall

Ex:

import re

email = '''Dear Customer:
The past due invoices listed below are still pending. This includes the 
following:

Invoice   Date     Purchase Order  Due Date  Balance
8754321   8/17/17  7200016508      9/16/18   140.72
5245344   11/7/17  4500199620      12/7/18   301.54

We would appreciate quick payment of these invoices.'''

email2 = """Hi - please confirm the status of below two invoices.

Invoice#               Amount               Invoice Date       Due Date          
7651234                $19,579.06          29-Jan-19           28-Apr-19            
9872341                $47,137.20          27-Feb-19           26-Apr-19 """

for eml in [email, email2]:
    print(re.findall(r"\b\d{7}\b", eml, flags=re.DOTALL))

Выход:

['8754321', '5245344']
['7651234', '9872341']
  • \b - границы регулярных выражений
  • \d{7} - получить 7-значный номер
1 голос
/ 08 мая 2019

Исходя из того, что Эндрю Аллен говорил, при условии, что эти 2 предположения верны:

  1. Номера счетов-фактур всегда ровно 7 цифр
  2. Счет-фактурачисла всегда следуют за пробелом и сопровождаются пробелом

Использование регулярных выражений должно работать.Что-то вроде:

import re

email = '''Dear Customer:
The past due invoices listed below are still pending. This includes the 
following:

Invoice   Date     Purchase Order  Due Date  Balance
8754321   8/17/17  7200016508      9/16/18   140.72
5245344   11/7/17  4500199620      12/7/18   301.54

We would appreciate quick payment of these invoices.'''

invoices = re.findall(r'\s(\d\d\d\d\d\d\d)\s', email)

invoice в этом случае имеет список из 2 строк: ['8754321', '5245344']

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...