Python re для разбора файла - PullRequest
0 голосов
/ 29 апреля 2018

Я пытаюсь проанализировать файл, который содержит несколько блоков. Файл выглядит так, как показано ниже.

$ Start of something1
.........contents
.........
$ End of something1
$ Start of something2
..........
..........
$ End of something2
some comments that should be included in block2.
$ Start of something3
.......
.......
$ End of something3

Мне удалось выполнить синтаксический анализ от первой строки ($ Start) до последней строки блока, который содержит "$ End of .....". Но проблема, с которой я столкнулся, была в основном для блоков типа 2-го в моем примере, где есть некоторые комментарии после конечного нижнего колонтитула. Я в основном должен найти $ Start в начале и найти следующий $ Start, но grep все перед следующим "$ Start". Заранее большое спасибо.

1 Ответ

0 голосов
/ 29 апреля 2018

Вы можете использовать позитивный взгляд, который не является частью группы захвата:

t = """$ Start of something1
.........contents
.........
$ End of something1
$ Start of something2
..........
..........
$ End of something2
some comments that should be included in block2.
$ Start of something3
.......
.......
$ End of something3""" 


import re

for k in re.findall(r'(\$ Start of .*?)(?=(?:\$ Start|\Z))',t,re.DOTALL|re.MULTILINE):
        print "------ new find --------" 
        print k  
        print "------- end ------------\n\n" 

Выход:

------ new find --------
$ Start of something1
.........contents
.........
$ End of something1

------- end ------------


------ new find --------
$ Start of something2
..........
..........
$ End of something2
some comments that should be included in block2.

------- end ------------


------ new find --------
$ Start of something3
.......
.......
$ End of something3
------- end ------------

Объяснение:

Шаблон захватывает группу, начинающуюся с литерала $ Start of, за которым следует как можно меньше символов (включая символы новой строки из-за re.DOTALL), так что за совпадением следует либо $ Start, либо \Z == конец строки .

(? = ..) является положительным взглядом, его содержимое (?: \ $ Start | \ Z) не является частью группы до него, и его собственная группа не захватывается.

  • 1-я группа захвата (\$ Start of .*?)
    • \$ буквально соответствует символу $ (с учетом регистра)
    • Start of соответствует символам Start of буквально (с учетом регистра)
    • .*? соответствует любому символу
      • *? Квантификатор - соответствует от нуля до неограниченного числа раз, насколько это возможно, с расширением по мере необходимости (ленивый)
  • Позитивный Lookahead (?=(\$ Start|\Z))
    • Утверждают, что приведенное ниже регулярное выражение соответствует
    • 2-я группа захвата (\$ Start|\Z)
      • 1-ая альтернатива \$ Start
        • \$ соответствует буквально символу $ (с учетом регистра)
        • Start соответствует символам Start буквально (с учетом регистра)
      • 2-й вариант \Z
        • \Z устанавливает позицию в конце строки или перед разделителем строки прямо в конце строки (если есть)

Глобальные флаги шаблонов

  • re.MULTILINE: многострочный. Заставляет ^ и $ совпадать с началом / концом каждая строка (не только начало / конец строки) re.

  • re.DOTALL: одна строка. Точка соответствует символам новой строки

Вы можете просмотреть объяснение в https://regex101.com/r/h27O0d/1, где я разработал регулярное выражение на основе вашего текста.

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