#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'