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