Использование регулярного выражения для разделения подразделов с уникальными заголовками

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

Каждый документ состоит из нескольких заголовков разделов, но все они имеют одну и ту же базовую структуру. Во-первых, есть заголовок «Аргумент», в котором суммируются замечания, высказанные в каждом из подразделов. Я хочу включить этот раздел «Аргументы», потому что некоторые документы в корпусе не имеют последующих подразделов; однако у подавляющего большинства из них есть эти разделы. Каждый подраздел начинается с римских цифр, а количество подразделов в каждом документе может варьироваться. Хотя я не знаю точно, сколько подразделов содержится в каждом документе, я предполагаю, что их не больше 10.

Для модального документа структура выглядит примерно так:

string = """ARGUMENT
Summary of argument

I. TITLE OF SUBSECTION 1
Text of subsection 1

II. TITLE OF SUBSECTION 2
Text of subsection 2

CONCLUSION
Text of conclusion
"""

Я создал сценарий регулярного выражения, чтобы попытаться разделить каждый раздел по его заголовку, используя re.split, обозначая заголовок ARGUMENT, подразделы с римскими цифрами от 1 (I) до 10 (X) и раздел ЗАКЛЮЧЕНИЕ, добавляя новые символы строк, чтобы избежать разделения в каждом экземпляре. этих слов/символов, независимо от того, присутствуют ли они в самих заголовках:

r'(\nARGUMENT|\nI\.|\nII\.|\nIII\.|\nIV\.|\nV\.|\nVI\.|\nVII\.|\nVIII\.|\nIX\.|\nX\.|\nCONCLUSION.*)'

Результат, который мне нужен, — это список, в котором каждый заголовок и результирующий текст под ним объединены в один элемент, как показано ниже:

['ARGUMENT  Summary of argument', 'I. TITLE OF SUBSECTION 1  Text of subsection 1', 'II. TITLE OF SUBSECTION 2  Text of subsection 2', 'CONCLUSION  Text of conclusion']

Однако при использовании re.split в приведенной выше строке мой фактический вывод отделяет римские цифры от остального текста этого раздела (обратите внимание на второй и четвертый элементы списка ниже:

['ARGUMENT\nSummary of argument\n', '\nI.', ' TITLE OF SUBSECTION 1\nText of subsection 1\n', '\nII.', ' TITLE OF SUBSECTION 2\nText of subsection 2\n', '\nCONCLUSION', '\nText of conclusion\n']

Символы новой строки в выводе для меня не особенно важны. Скорее, для меня важнее всего объединение заголовка и текста под ним.

Могу ли я внести какие-либо изменения в свой сценарий регулярного выражения, чтобы получить первый результат, а не второй? Или, если нет, есть ли какая-то другая команда регулярного выражения, которую я мог бы использовать для достижения этого конкретного результата? И, что менее важно, существует ли более эффективный или упрощенный способ сопоставить заголовки разделов с римскими цифрами от I до X в моем сценарии?

🤔 А знаете ли вы, что...
Python имеет богатую стандартную библиотеку, включая модули для работы с текстом, файлами и сетями.


3
63
1

Ответ:

Решено

В шаблоне просто отсутствуют некоторые инструкции о том, где и что разбить по предоставленным вами шаблонам. Я написал этот шаблон, который дает дополнительные инструкции о том, где разделить строку и удалить избыточность римских цифр.

string = """ legal doc """

pattern = r'(?=\b(?:[IVXL]+\.)|CONCLUSION)'
answer = re.split(pattern, string)
answer = [line.replace('\n', ' ').strip() for line in answer]

print(answer)

Предполагая, что юридические документы будут иметь ту же структуру, мы можем игнорировать часть ARGUMENT и разделить текст, начиная с первой точки.

pattern = r'(?=\b(?:[IVXL]+\.)|CONCLUSION)'

Итак, в ?= включаем и ищем нужный узор. \b — граница слова, она помогает предотвратить разделение больших римских цифр. ?: не фиксируется, чтобы предотвратить появление избыточных элементов в окончательном ответе. В [IVXL]+ мы просим найти символы, которые могут повторяться, а затем, используя \., мы требуем, чтобы римская цифра заканчивалась точкой. CONCLUSION просто разделяет последний абзац и его содержимое.

answer = [line.replace('\n', ' ').strip() for line in answer]

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