2015-10-18 3 views
2

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

У меня есть длинный текстовый файл примерно в такой форме:

Начало тестовой АБВ:

несколько строк бла-бла-бла

начала испытания wzy:

несколько строк бла-бла-бла

начала испытания QQQ:

несколько строк бла-бла-бла

Я хочу, чтобы захватить все вещи после «Начало испытаний» замедления, и это выражение получает меня примерно половину того, что мне нужно:

re.findall(r'Start of test(.+?)Start of test', curfile, re.S) 

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

Я предполагаю, что мне нужно использовать отрицательные утверждения LOOKAHEAD, но я не много удачи выяснить, как правильно их использовать, я пытался вещи, как:

re.findall(r'Start of test(.+?)(?!Start of test) 

, который не дает никакой полезной Результаты.

ответ

1

Я думаю, что это шаблон, который вы ищете

Start of test(.+?)(?=Start of test|$)

Тогда ваш новый код должен быть

re.findall(r'Start of test(.+?)Start of test', curfile, re.S) 

см demo

0

Вы хотите, чтобы смотровой рисунок. См https://docs.python.org/2/library/re.html, где он описывает (?= ... ):

(?=...)
Пропускать ... матчи следующих, но не потребляют строку. Это называется ожидаемым утверждением. Например, Isaac (?=Asimov) будет соответствовать 'Isaac ', только если за ним следует 'Asimov'.

Так что для вашего случая:

re.findall(r'Start of test(.+?)(?=Start of test)', curfile, re.S) 

Но это должно быть закаленным с не жадными оценками.

+0

Это выражение получает меня на 99%, но он пропускает последний кусок, как бы я решил это? – user3552664

+0

За последним фрагментом не следует «Начало теста», поэтому вам нужно будет либо «(? = Начало теста)», либо «$» после '(. +?)'. –

+0

@ user3552664: Может быть, добавить в конец текста строку «Начало теста»: 're.findall (r'Start of test (. +?) (? = Начало теста) ', curfile +" \ nStart of test ", re.S)' – wallyk

0

Возможно, было бы полезно использовать re.finditer для получения итерации объектов соответствия, а затем использовать mo.start(0) для каждого объекта совпадения, чтобы узнать, где в исходной строке находится текущее совпадение.Затем, вы можете восстановить все, что в перерывах между матчами в следующим образом - обратите внимание, что мой образец соответствует только один «Старт тест» линии:

pattern = r'^Start of test (.*):$' 
matches = re.finditer(pattern, curfile, re.M) 
i = 0 # where the last match ended 
names = [] 
in_between = [] 
for mo in matches: 
    j = mo.start(0) 
    in_between = curfile[i:j] # store what came before this match 
    i = mo.end(0) # store the new "end of match" position 
    names.append(mo.group(1)) # store the matched name 
in_between.append(curfile[i:]) # store the rest of the file 

# in_between[0] is what came before the first test 
chunks = in_between[1:] 
Смежные вопросы