2015-01-04 4 views
2

CODE2의 코드가 작동하는 이유를 이해해주십시오. 제 생각에 re.compile은 객체를 반환하고 원하는 결과를 얻으려면 search, match, findall 등과 같은 메소드를 지정합니다.re.compile 동작에 대해 혼란 스럽습니다.

내가 혼동스럽게 생각하는 것은 re 검색과 같은 모듈 수준 함수가 컴파일 된 abject를 매개 변수로 받아 들일 수있는 방법입니다. CODE2

코드 1을 참조하십시오

In [430]: p = re.compile(r'(\b\w+)\s+\1') 
In [431]: p.search('Paris in the the spring').group() 
Out[431]: 
'the the' 

CODE 2

In [432]: re.search(p, 'Paris in the the spring').group() 
Out[432]: 
'the the' 

답변

3

re.search의 첫 번째 인수, 즉 재 패턴 문자열, 것으로 설명되어 있지 컴파일 RE 객체 - 어쩌면 더 좋은 디자인은 다형성을 받아 들일 수 있었을 것이지만, 슬프게도! re 모듈이 개발 될 때, 그것은 단지 ho가 아닙니다. 우리가 해냈어. 아 글쎄, 적어도이 re 컴파일 된 객체의 방법을 모방하는 re의 모든 모듈 기능에서 단지 동일합니다 -!) 그러나

, 파이썬의 긴 역사적으로 유명한 역사의 어느 시점에서, 누군가가 우리의 원래 어긋나 고정 디자인 (나는 그 일이 언제 일어 났는지 말할 수 없다!) : 요즘 대부분 re 함수가 첫 번째 pattern 인자는 여전히 RE 패턴 문자열이어야하고, 몇 가지는 이제 "문자열 또는 RE 일 수있다. 개체 "... 그리고 모두은 (더!) 방법으로 작동하는 것처럼 보입니다. 당신이 (대부분)이 문서에 따르면, 이론에서 컴파일 re, 이있는 경우

그래서, 당신은 메서드를 호출해야합니다 (그것은 조각의 아주 짧은에서 제외하고, 일반적으로 가장 좋은 방법입니다)보다는 re.search과 같은 모듈 수준 함수 re으로 전달하십시오. 그러나 실제로의 경우 컴파일 된 re 개체는 문서화 된 RE 패턴만큼이나 훌륭합니다.

Man, "Python in a Nutshell"의 제 3 판 (두 명의 공동 저자들과 함께)을 준비하기 시작한 것 같이 좋은 점은 ... "적어도 문서를 고칠 것" 해당! -)

추가 : 평소와 같이 속도를 측정하려면 timeit 님의 친구입니다!

$ python -mtimeit -s'import re; s="paris in the spring"; mre=re.compile("paris")' 're.match("paris", s)' 
1000000 loops, best of 3: 1.38 usec per loop 

은 대 : 그래서

$ python -mtimeit -s'import re; s="paris in the spring"; mre=re.compile("paris")' 'mre.match(s)' 
1000000 loops, best of 3: 0.468 usec per loop 

, 전체, 당신은 re 기능을 당신을 위해 모든 것을 처리시키는 것보다, 한 번 re.compile 보내고 일 약 3 배 더 빠르게 얻을 수 있습니다. re.compile 접근 방식의 팬인 이유를 확인하십시오. -)

또한 "더 빠름"은 "더 많은 Pythonic"("Python의 관용", 다른 말로하면)과 강하게 관련이 있습니다. 두 사람 중 어느 쪽이 접근했는지 확실하지 않으면 timeit (적절하게는 명령 줄 접근 방식 python -mtimeit)을 사용하십시오. 두 접근법 중 어느 것이 더 빨리 안정적으로 수행된다면 그 접근법은 더 Pythonic입니다!-)

+0

'아아'란 무엇입니까? –

+0

'define : alas'에 대한 웹 검색에서는 슬픔, 동정 또는 염려의 표현입니다. 나는 ** 후회 **의 표현으로 그것을 실제로 사용하고 있었다. (아마 그 모듈을 잘못 설계하는 데 도움을 준 것에 대한 나의 책임감을 위해, 또는 잘못된 설계 돛을 내버려두기 - 너무 늦어서 지금 그것을 바꿀 수는 없다.) - 그러나 나는 그것이 "슬픔, 동정 또는 염려"에 충분히 가깝기를 바란다. (영어가 나의 제 3의 언어이기 때문에 나는 그것을 올바르게 사용한다면 나는 결코 자신감을 가질 수 없다. 미국 태생의 아내와 나의 편집자는 모두 대부분의 원어민보다 더 잘 사용합니다. –

+0

글쎄 영어가 내 것이 아니기 때문에 내가 물었습니다 :-) –

1

re 모듈의 모든 기능을 사용하면 패턴 문자열 대신 패턴 개체를 지정할 수 있습니다. 이미 패턴이있는 경우 새 패턴 객체를 만드는 것을 피할 수있는 단순화/최적화 기능입니다.


내가 명시 적으로이 문제를 언급 문서 도구 링크를 찾을 수 없습니다,하지만 당신은 소스 코드 1 볼 경우 당신은 아주 쉽게 볼 수 있습니다. 시작하려면 re.compile에 대한 implementation입니다 :이 기능은 _compile라는 이름의 또 다른 함수를 호출하지만 아무것도하지 않는 방법

def compile(pattern, flags=0): 
    "Compile a regular expression pattern, returning a pattern object." 
    return _compile(pattern, flags) 

알 수 있습니다. 이 함수는 실제로 패턴 객체를 만듭니다. re.compile은 별칭 일뿐입니다.


에 이동, re.search에 대한 implementation은 다음과 같습니다 당신이 볼 수 있듯이, re.search 기능에 대한 특별한 것은 또한

def search(pattern, string, flags=0): 
    """Scan through string looking for a match to the pattern, returning 
    a match object, or None if no match was found.""" 
    return _compile(pattern, flags).search(string) 

없다. re._compile에 의해 반환 된 패턴 객체의 search 메소드를 호출합니다.

re.search(p, 'Paris in the the spring').group() 

를 동일하다 :이 일을하는 것을 의미한다 re._compile 당신이 패턴 문자열로 패턴 개체를 전달할 수 있습니다 이유

re._compile(p).search('Paris in the the spring').group() 

그래서 당신이 요청해야하는 문제입니다. 이전과 같이, 대답은 implementation 보면 찾을 수 있습니다 당신이 볼 수 있듯이

def _compile(pattern, flags): 
    ... 
    if isinstance(pattern, _pattern_type): 
     if flags: 
      raise ValueError(
       "Cannot process flags argument with a compiled pattern") 
     return pattern 

_compile 함수는 pattern 인수가 이미 패턴 객체입니다 있는지 확인하기 위해 검사를 수행합니다. 그렇다면, 단순히 그것을 반환하고 새로운 것을 구축하는 것을 피합니다. 해진다

re._compile(p).search('Paris in the the spring').group() 

:

re.search(p, 'Paris in the the spring').group() 

을 동등하다 :이 수행하는 것을 의미

p.search('Paris in the the spring').group() 

1이 CPython의 소스 코드이다.

관련 문제