Как разбить большой документ на небольшие документы на основе шаблона с использованием регулярного выражения?

#python #regex

#python #регулярное выражение

Вопрос:

Большой документ состоит из небольшого документа, разделенного шаблоном типа «1 из 1435 ДОКУМЕНТОВ». Я хочу разбить его на 1435 небольших документов.

  re_1 =  r"d{1,4} of d{1,4} DOCUMENTS. ?"

 re_2 =  r"d{1,4} of d{1,4} DOCUMENTS. "
  

re_1 выдает мне только «1 из 1435 ДОКУМЕНТОВ» и т.д.
re_2 дает мне весь документ.

Есть ли способ использовать re.findall с правильным регулярным выражением? или я должен выполнить re.split (что в данном случае проще всего) или, альтернативно, перебирать каждую строку и проверять наличие шаблона? Спасибо!

 1 of 1435 DOCUMENTS
blabla (multiple lines)

2 of 1435 DOCUMENTS
blabla(multiple lines)
3 of 1435 DOCUMENTS
blabla(multiple lines)
4 of 1435 DOCUMENTS
blabla(multiple lines)

5 of 1435 DOCUMENTS
....
  

Комментарии:

1. Вы можете использовать re.split(r'(?!A)(?=^d{1,4} of d{1,4} DOCUMENTS)', text, flags=re.M) с Python 3.7

2. Полезно знать. Спасибо!

Ответ №1:

В более ранних версиях Python до версии 3.7 вы можете использовать re.findall с

 r'(?sm)^d{1,4} of d{1,4} DOCUMENTS.*?(?=^d{1,4} of d{1,4} DOCUMENTS|Z)'
  

Смотрите демонстрацию регулярных выражений

Подробные сведения

  • (?sm) re.M и re.S опции на
  • ^ — начало строки
  • d{1,4} of d{1,4} DOCUMENTS — От 1 до 4 цифр, пробел, of , пробел, от 1 до 4 цифр, пробел и DOCUMENTS подстрока
  • .*? — любые 0 или более символов, как можно меньше, вплоть до ближайшего
  • (?=^d{1,4} of d{1,4} DOCUMENTS|Z) ^d{1,4} of d{1,4} DOCUMENTS шаблон или ( | ) конец строки ( Z ).

Смотрите демонстрацию Python:

 import re
s = "TEXT_HERE"
print(re.findall(r'^d{1,4} of d{1,4} DOCUMENTS.*?(?=d{1,4} of d{1,4} DOCUMENTS|Z)', s, re.M | re.S))
# => ['1 of 1435 DOCUMENTSnblabla (multiple lines)nn', '2 of 1435 DOCUMENTSnblabla(multiple lines)n', '3 of 1435 DOCUMENTSnblabla(multiple lines)n', '4 of 1435 DOCUMENTSnblabla(multiple lines)nn', '5 of 1435 DOCUMENTSn....']
  

С Python 3.7, где re.split можно разделить с совпадениями нулевой длины, вы можете использовать

 r'(?m)(?!A)(?=^d{1,4} of d{1,4} DOCUMENTS)'
  

Смотрите демонстрацию регулярных выражений.

Подробные сведения

  • (?m) re.M опция включена
  • (?!A) — не в начале строки — (?=^d{1,4} of d{1,4} DOCUMENTS) — сразу справа должно быть начало строки, от 1 до 4 цифр, пробел, of , пробел, от 1 до 4 цифр, пробел и DOCUMENTS подстрока

Использование:

 re.split(r'(?!A)(?=^d{1,4} of d{1,4} DOCUMENTS)', text, flags=re.M)