Неоднократно извлекайте строку между двумя разделителями в текстовом файле, Python

У меня есть текстовый файл в следующем формате:

DELIMITER1
extract me
extract me
extract me
DELIMITER2

Я хотел бы извлечь каждый блок extract me между DELIMITER1 и DELIMITER2 в .txt файле

Это мой текущий, неработающий код:

import re
def GetTheSentences(file):
     fileContents =  open(file)
     start_rx = re.compile('DELIMITER')
     end_rx = re.compile('DELIMITER2')

     line_iterator = iter(fileContents)
     start = False
     for line in line_iterator:
           if re.findall(start_rx, line):

                start = True
                break
      while start:
           next_line = next(line_iterator)
           if re.findall(end_rx, next_line):
                break

           print next_line

           continue
      line_iterator.next()

Любые идеи?

Ответ 1

Вы можете упростить это до одного регулярного выражения, используя re.S, флаг DOTALL.

import re
def GetTheSentences(infile):
     with open(infile) as fp:
         for result in re.findall('DELIMITER1(.*?)DELIMITER2', fp.read(), re.S):
             print result
# extract me
# extract me
# extract me

Это также использует нежирный оператор .*?, поэтому будут найдены многочисленные неперекрывающиеся блоки пар DELIMITER1-DELIMITER2.

Ответ 2

Это должно делать то, что вы хотите:

import re
def GetTheSentences(file):
    start_rx = re.compile('DELIMITER')
    end_rx = re.compile('DELIMITER2')

    start = False
    output = []
    with open(file, 'rb') as datafile:
         for line in datafile.readlines():
             if re.match(start_rx, line):
                 start = True
             elif re.match(end_rx, line):
                 start = False
             if start:
                  output.append(line)
    return output

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

Ответ 3

Если разделители находятся внутри строки:

def get_sentences(filename):
    with open(filename) as file_contents:
        d1, d2 = '.', ',' # just example delimiters
        for line in file_contents:
            i1, i2 = line.find(d1), line.find(d2)
            if -1 < i1 < i2:
                yield line[i1+1:i2]


sentences = list(get_sentences('path/to/my/file'))

Если они находятся в их собственных строках:

def get_sentences(filename):
    with open(filename) as file_contents:
        d1, d2 = '.', ',' # just example delimiters
        results = []
        for line in file_contents:
            if d1 in line:
                results = []
            elif d2 in line:
                yield results
            else:
                results.append(line)

sentences = list(get_sentences('path/to/my/file'))

Ответ 4

Это хорошая работа для понимания List, не требуется никакого регулярного выражения. Первый список comp сбрасывает типичный \n в списке текстовых строк, который открывается при открытии txt файла. Второй список comp просто использует оператор in для идентификации шаблонов последовательностей для фильтрации.

def extract_lines(file):
    scrubbed = [x.strip('\n') for x in open(file, 'r')]
    return [x for x in scrubbed if x not in ('DELIMITER1','DELIMITER2')]