Python 3.2: как разбить многострочные строки на разделы, используя группы строк

#regex #python-3.x

#регулярное выражение #python-3.x

Вопрос:

У меня есть файл групп данных в нескольких строках. Каждому разделу строк данных предшествуют две строки, которые начинаются с хэш-меток (#), за которыми следует новая строка (‘ n’), ряд тире (‘-‘), затем еще две новые строки.

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

 # Comment
# Comment
data for section 1
data for section 1
...
last line of data for section 1

--------------------------------------------------

# Comment
# Comment
data for section 2
data for section 2
...
last line of data for section 2

--------------------------------------------------

...
  

Я хочу разбить этот файл на каждую из групп, которые окружены таким образом, чтобы я мог обрабатывать их по отдельности. Поскольку самый простой язык, который у меня есть для обработки файлов, — Python 3.2, я попытался создать регулярное выражение для выполнения этого разделения. К сожалению, я не могу заставить разделение работать.

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

 with open('original.out') as temp:
    original = temp.read()
print(re.findall(r'^$|^[#-].*$', original, re.MULTILINE))
  

Но когда я пытаюсь передать это же регулярное выражение в re.split() , оно просто возвращает весь файл.

Как я могу построить этот список разделов так, как мне нужно, и чего мне не хватает в моем понимании регулярных выражений (или того, как Python обрабатывает их), что помогло бы мне увидеть решение?

Ответ №1:

быстрое и грязное решение на основе генератора

 from collections import deque

# yield each section
def gen_sections(lines):
   breaker = deque(maxlen=3)
   section = []
   check = [
      lambda line: not line.strip(),       # blank
      lambda line: line.startswith('---'), # dashed line
      lambda line: not line.strip()        # blank
   ]
   for line in lines:
      line = line.strip()
      breaker.append(line)
      section.append(line)
      if len(breaker) == 3 and all(f(x) for f,x in zip(check, breaker)):
         yield 'n'.join(section[:-len(breaker)])
         section = []

# wrap file in this to remove comments
def no_comments(lines):
   for line in lines:
      line = line.strip()
      if not line.startswith('#'):
         yield line

for section in gen_sections(open('file.txt')):
  print section, 'n'