2009-08-10 2 views
3

줄 단위로 파일을 처리하는 파이썬 스크립트가 있습니다. 줄이 정규식과 일치하면 처리하는 함수를 호출합니다.내 파이썬 스크립트 리팩토링에 도움이 필요합니다

내 질문에 내 스크립트가 리팩터링 (refactor)에 더 잘 작성되었습니다. 스크립트가 작동하지만 그대로, 내 파일에 대한 정규식을 추가 할 때 편집기 오른쪽에 들여 쓰기를 유지해야합니다.

감사드립니다. 지금 내 코드는 다음과 같이 끝 :

 
for line in fi.readlines(): 

     result= reg1.match(line) 

     if result: 
       handleReg1(result) 

     else: 
       result = reg2.match(line) 

       if result: 
         handleReg2(result) 
       else: 
         result = reg3.match(line) 

         if result: 
           handleReg3(result) 
         else: 
           result = reg4.match(line) 

           if result: 
             handleReg4(result) 
           else: 
             result = reg5.match(line) 

             if result: 
               handleReg5(result) 
+4

elif를 피하는 이유는 무엇입니까? – balpha

답변

12

내가 기능으로 데이터 구조 매핑 정규 표현식에 사용으로 전환 것입니다. 뭔가 같은 :

map = { reg1: handleReg1, reg2: handleReg2, etc } 
다음

그들을 통해 방금 루프 : 당신이 특정 순서로 발생하는 경기를해야하는 경우

for reg, handler in map.items(): 
    result = reg.match(line) 
    if result: 
     handler(result) 
     break 

당신이 사전 대신 목록을 사용해야하지만, 교장은 동일합니다.

+0

이것은 내가 권장하는 접근법입니다. 샘 (sam)이 언급했듯이 특정 순서가 필요할 경우리스트를 사용하고자한다. 아마도 핸들러 = [(reg1, handleReg1), (reg2, handleReg2), ...]'와 같은 식으로, 다음과 같이 :'for (reg, handler) in 핸들러 : – Amber

+1

당신은 분명히 사전이 아니라 목록을 원한다. 여기서 키 룩업은 없습니다. 이것은 정규 표현식과 함수 사이의 연관입니다. 튜플 목록이 좋습니다. – hughdbrown

1

여기에 사소한 하나 :이 코드를 붙여 넣은 코드는 다른 것 몇 가지 regexps '에 일치하는 라인이있을 수

handlers = { reg1 : handleReg1, ... } 

for line in fi.readlines(): 
    for h in handlers: 
     x = h.match(line) 
     if x: 
      handlers[h](x) 

경우는 여러 핸들러를 호출합니다. regexps가 다른 순서로 시도 될 것이므로 break을 추가하면 도움이되지 않으므로 잘못된 번호를 호출하게됩니다. 당신은 하나 개의 거대한 정규 표현식으로 모든 regexps '에 결합하고 일치하는 감지() m.group 사용하는 것입니다 작동 할 수

handlers = [ (reg1, handleReg1), (reg2, handleReg2), ... ] 

for line in fi.readlines(): 
    for reg, handler in handlers: 
     x = reg.match(line) 
     if x: 
      handler(x) 
      break 
+0

동일하지 않습니다. 당신의 방법은 여러 핸들러를 호출 할 수 있습니다. 그의 전화는 많아야 하나. – balpha

+0

위의 버전은 reg1, reg2와 다른 순서로 regexps를 시도 할 수 있기 때문에 동일하지 않습니다. –

0

또 다른 방법 :이 경우 경우 그래서 당신은 목록을 반복해야한다. 내 직감은 이것이 더 빨라야한다고 말하지만, 나는 그것을 테스트하지 않았다.

>>> reg = re.compile('(cat)|(dog)|(apple)') 
>>> m = reg.search('we like dogs') 
>>> print m.group() 
dog 
>>> print m.groups() 
(None, 'dog', None) 

테스트하려는 정규식이 그 자체로 복잡하거나 일치 그룹을 사용하면 복잡해집니다.

+0

매우 빠르며 복잡하고 일치 그룹을 사용하는 내부 regexps에 대한 해결책은 주위에 명명 된 그룹을 사용하는 것입니다 ("네임 스페이스"에서, 예를 들어 내부 접두사가 붙은, 내부 정규 표현식에서 사용될 수있는 명명 된 그룹의 쌍점). –

관련 문제