Средство сопоставления многострочных строк с необязательной промежуточной фразой

Я хотел бы взять текст, распределенный между двумя строками.

Например :

PO Number Dept.number
4000813852 7

Я хотел бы получить номер заказа 4000813852. Это похоже на данные в виде таблицы, но в контексте всего документа выглядит как обычный текст.

Я использовал re.MULTILINE как r'PO Number.*\n[0-9]+'

в этом случае он работает, но это не лучшее решение, потому что, возможно, номер заказа находится посередине как

Invoice Number PO Number Dept.number
123456666     4000813852  7

person ahmed osama    schedule 05.08.2018    source источник
comment
Последний случай недооценен и не подходит для регулярного выражения - вам нужно как-то угадать, какое число принадлежит PO - нам потребуется гораздо больше данных, чтобы что-нибудь подобрать. Вы захватываете слишком много текста с помощью своего регулярного выражения, поскольку не используете группы захвата. Напишите синтаксический анализатор на основе строк / столбцов и скармливайте ему части, начиная с полной строки, содержащей номер заказа, до конца следующей строки   -  person Patrick Artner    schedule 05.08.2018
comment
@ahmed какое-нибудь решение сработало для вас? Если это так, подумайте о том, чтобы принять указанный ответ. Как это сделать, см. здесь.   -  person Paolo    schedule 06.08.2018
comment
На самом деле, если вы не можете применить специальные знания, например, номера заказов - это 10 цифр, номера отделов - 1-3 в многострочном регулярном выражении, тогда @PatrickArtner прав. Сначала запишите имена полей из первой строки. Затем выясните, какие поля из второй строки вам нужны.   -  person smci    schedule 06.08.2018


Ответы (2)


Вы можете сделать это с двумя группами захвата и включенной опцией re.DOTALL. Выражение предполагает, что интересующее вас число - единственное, содержащее 10 цифр в вашем тексте.

Выражение:

(PO\sNumber).*(\d{10})

Фрагмент Python:

import re

first_string = """PO Number Dept.number
4000813852 7"""

second_string = """Invoice Number PO Number Dept.number
123456666     4000813853  7"""

PO_first = re.search(r'(PO\sNumber).*(\d{10})',first_string,re.DOTALL)
print(PO_first.group(1)+" "+PO_first.group(2))

PO_second = re.search(r'(PO\sNumber).*(\d{10})',second_string,re.DOTALL)
print(PO_second.group(1)+" "+PO_second.group(2))

Вывод:

PO Number 4000813852
PO Number 4000813853
person Paolo    schedule 05.08.2018

С одним регулярным выражением:

data="""PO Number Dept.number
    4000813852 7
    Invoice Number PO Number Dept.number
    123456666     4000813852  7
    """

re.findall(r"(PO Number)\s*Dept.number\s*(?:(?:\d+)\s+(\d+)|(\d+))\s+\d",data)
Out: 
[('PO Number', '', '4000813852'), ('PO Number', '4000813852', '')]

Я не использую re.MULTILINE, так как \ s тоже соответствует новой строке.

person kantal    schedule 05.08.2018
comment
Это не одна струна, это две разные струны. - person Paolo; 06.08.2018
comment
@UnbearableLightness это не одна строка. Не проблема, вы можете применить мое регулярное выражение и для одной строки. - person kantal; 06.08.2018