2010-11-20 4 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

항목은 무엇입니까 : finditer 수익률 MatchObject S와 문자열이 아니라, 단지 .group() 전화 일치하는 문자열을 얻기 위해? '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'). '다시'는 필요 없다. 가장 중요한 문제는 클린업의 문제입니다. – user225312

+0

@sukhbir - 항목이 OP가 지정된대로 줄을 가로 지르는 경우 true가 아닙니다. – bgporter

+0

답변 해 주셔서 감사합니다. 제가 필요한 것입니다. http://stackoverflow.com/questions/4248010/how-to-exclude-comment-lines-when-searching-with-regular-expression에서 후속 질문 – tnt

0

filecontents.split ('& CRB')을 사용하고 각 줄을 정규 표현식으로 구문 분석합니다 (re 모듈 참조).

1

01 대신에 re.finditer을 사용하고 싶습니다.은 파싱하는 파일의 크기를 한 번에 알지 못하기 때문에 너무 많은 양을 소비 할 수 있습니다. 결과를 산출하는 반복자를 사용하면 프로그램에서 너무 많은 RAM을 먹는 것을 막을 수 있습니다.

그래서 최선의 해결책은 the one posted by bgporter이며 for 루프에서 pat.findall 대신 pat.finditer를 사용하는 것입니다.

for entry in pat.finditer(s): 
    entry_text = entry.group() 
    #do something with entry_text. 
관련 문제