2010-11-20 2 views
1

содержание текста файла:Лучший способ перебора записей, разделенных двумя ключевыми словами?

&CRB A='test1' B=123,345, 678 &END 
Misc text potentially between entries ... 
&CRB A='test2' 
      B=788, 345, 3424 &END 
&CRB A='test3' 
      B=788, 345, 3424 &END 
&CRB A='test4' B=788, 345, 3424 &END 

Что является наиболее эффективным способом для перебора записей между ключевыми словами? Примечание , что некоторые записи охватывают строки. Требуется следующее:

f = open(filename) 
for entry in f: 
    - do something with entry 

Конечно, это не так просто. Но есть ли предложения по прямому способу повторить тщательную проверку записей, разделенных двумя ключевыми словами.

+0

Что такое запись? 'A = 'test1' B = 123,345, 678',' A = 'test1'' или '123'? –

+1

Насколько велик файл? Все плакаты предполагают, что они будут прочитаны в памяти и проанализированы там. Скорее всего, это хорошее предположение для 99% практических примеров? Но если нет, вам, вероятно, потребуется прочитать его по строкам и собрать записи. – mjhm

ответ

4

Предполагая, что запись всего текста между &CRB и &END пар, вы можете вытащить текст между ними что-то вроде этого:

import re 

# the regular expression treats newlines as a regular character, so the 
# multiline entries are okay. It's non-greedy, so it gets individual entries. 
pat = re.compile(r'&CRB(.+?)&END', re.DOTALL) 

s = ''' &CRB A='test1' B=123,345, 678 &END 
Misc text potentially between entries ... 
&CRB A='test2' 
      B=788, 345, 3424 &END 
&CRB A='test3' 
      B=788, 345, 3424 &END 
&CRB A='test4' B=788, 345, 3424 &END''' 

for entry in pat.findall(s): 
    # do something with each entry 
    print entry 

печатает это:

A='test1' B=123,345, 678 
    A='test2' 
      B=788, 345, 3424 
    A='test3' 
      B=788, 345, 3424 
    A='test4' B=788, 345, 3424 

. .. это ваша проблема, чтобы очистить и интерпретировать содержимое каждой из этих записей ...

+0

'[line.strip ('& CRB'). Strip ('& END'). Strip() для строки в открытом ('файл')]'. Нет необходимости в 're'. Основная проблема заключается в очистке :) – user225312

+0

@sukhbir - не верно, если записи могут охватывать разные строки, как указано OP. – bgporter

+0

Спасибо за ваш ответ - это то, что мне было нужно. Последующий вопрос на http://stackoverflow.com/questions/4248010/how-to-exclude-comment-lines-when-searching-with-regular-expression – tnt

0

Я бы прочитал в файле, используйте filecontents.split ('& CRB'), а затем проанализируйте каждую строку с помощью регулярных выражений (см. Модуль re).

1

Я бы использовал re.finditer вместо re.findall, так как мы не знаем, что размер файла, анализируя его за один раз, может быть слишком много потребляемого, тогда как наличие итератора, дающего результаты, не позволит программе переваривать слишком много ОЗУ.

Поэтому я считаю, что лучшим решением является the one posted by bgporter, используя pat.finditer вместо pat.findall в цикле for. дает finditer MatchObject s, а не строки, чтобы получить строки, совпавшие просто позвоните .group():

for entry in pat.finditer(s): 
    entry_text = entry.group() 
    #do something with entry_text. 
Смежные вопросы