Извлечение текста из шаблона 1 в шаблон 2 — Python

#python #regex #python-2.7

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

Вопрос:

У меня есть входной файл, как показано ниже

 PATTERN1 PTR1 blah blah blah
needThis  blah blah blah
thisOneAsWell  blah blah blah
PATTERN2

PATTERN1 PTR2 blah blah blah
needThis  blah blah blah
thisOneAsWell  blah blah blah
PATTERN2 

............................
............................

PATTERN1  PTRN blah blah
needThis  blah blah blah
thisOneAsWell blah blah blah
PATTERN2
  

Мне нужно, чтобы моя функция возвращала только первые записи столбцов из ШАБЛОНА 1 в ШАБЛОН 2, как показано ниже,

 PTR1
needThis thisOneAsWell

PTR2
needThis thisOneAsWell

......................
......................
PTRN
needThis thisOneAsWell
  

PTR1 , PTR2 …… PTRN — это разные тексты. ШАБЛОН 1 и ШАБЛОН 2 разные, но постоянно присутствуют в файле.

Как я могу добиться этого в Python?

Я все еще новичок в Python, и я пытаюсь добиться этого, используя re.findall(), не получая желаемого ввода / вывода:

 def retrieve():
    file = open("fileName","r")
    string = re.findall(r"PATTERN1",file.read())
    print string
  

Ответ №1:

Вы могли бы вложить два регулярных выражения:

 txt='''
PATTERN1 PTR1 blah blah blah
needThis1  blah blah blah
thisOneAsWell1  blah blah blah
PATTERN2

PATTERN1 PTR2 blah blah blah
needThis2  blah blah blah
thisOneAsWell2  blah blah blah
PATTERN2 

............................
............................

PATTERN1  PTRN blah blah
needThisN  blah blah blah
thisOneAsWellN blah blah blah
PATTERN2'''

import re

for m in re.finditer(r'^PATTERN1s*(.*?)(?=^PATTERN2)', txt, re.M | re.S):
    print re.findall(r'(^w )', m.group(1), re.M)
  

С принтами:

 ['PTR1', 'needThis1', 'thisOneAsWell1']
['PTR2', 'needThis2', 'thisOneAsWell2']
['PTRN', 'needThisN', 'thisOneAsWellN']
  

редактировать 1

Если вы используете файл, который легко поместится в памяти:

 with open(fn) as f:
    txt=f.read()
    for m in re.finditer(r'^PATTERN1s*(.*?)(?=^PATTERN2)', txt, re.M | re.S):
        print re.findall(r'(^w )', m.group(1), re.M)
  

Используйте mmap для файлов большего размера, которые с трудом помещаются в памяти.


редактировать 2

Просто добавьте результаты в список после объединения в строку:

 with open(fn) as f:
    results=[]
    txt=f.read()
    for m in re.finditer(r'^PATTERN1s*(.*?)(?=^PATTERN2)', txt, re.M | re.S):
        results.append('n'.join(re.findall(r'(^w )', m.group(1), re.M))
    print 'n===n'.join(results)
  

Комментарии:

1. спасибо, однако мой вводимый текст может отличаться, и поэтому мне придется использовать file = open()

2. Вы можете сделать то же самое с открытым файлом. Просто прочитайте содержимое файла в строку. Я просто использовал txt строку в качестве примера.

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

4. Что вы подразумеваете под возвращением конечного результата ?

5. Вместо того, чтобы печатать re.findall() , мне нужно вернуть это вызывающему.

Ответ №2:

 import re
with open('file', 'r') as f:
    content = f.read()
    matches = re.findall(r'PATTERN1(.*?)PATTERN2', content, re.MULTILINE|re.DOTALL)

for match in matches:
    for line in match.split('n'):
        columns = line.split()
        if columns:
            print(columns[0])
  

Комментарии:

1. спасибо, но ваша функция возвращает весь текст между шаблоном 1 <=> шаблоном 2 .