re.search와 re.match의 차이점은 무엇입니까?


526

파이썬 모듈 에서 search()match()함수 의 차이점은 무엇입니까 ?re

나는 문서 ( 현재 문서 )를 읽었 지만 결코 기억하지 못하는 것 같습니다. 계속 찾아보고 다시 배워야합니다. 나는 누군가가 예를 들어 명확하게 대답하여 내 머릿속에 붙어 있기를 바라고 있습니다. 또는 적어도 내 질문으로 돌아갈 수있는 더 좋은 곳이 있으며 다시 배우는 데 시간이 덜 걸립니다.

답변:


508

re.match문자열의 시작 부분에 고정됩니다. 그것은 개행과 관련이 없으므로 ^패턴에서 사용하는 것과 동일하지 않습니다 .

현상태대로 re.match 설명서를 말한다 :

문자열시작 부분에 0 개 이상의 문자가 정규식 패턴과 일치하면 해당 MatchObject인스턴스를 리턴하십시오 . None문자열이 패턴과 일치하지 않으면 반환 합니다. 이것은 길이가 0 인 일치와 다릅니다.

참고 : 문자열의 어느 곳에서나 일치하는 항목을 찾으려면 search() 대신 사용하십시오.

re.search설명서 에서 알 수 있듯이 전체 문자열을 검색합니다 .

문자열을 스캔하여 정규식 패턴이 일치하는 위치를 찾고 해당 MatchObject인스턴스를 리턴하십시오 . None문자열에서 패턴과 일치하는 위치가 없으면 반환 합니다. 이것은 문자열의 어느 시점에서 길이가 0 인 일치 항목을 찾는 것과 다릅니다.

따라서 문자열의 시작 부분에서 일치하거나 전체 문자열과 일치 해야하는 경우을 사용하십시오 match. 더 빠릅니다. 그렇지 않으면를 사용하십시오 search.

문서는이 특정 섹션 matchsearch 또한 여러 문자열을 포함 :

파이썬은 정규 표현식을 기반으로 두 가지 다른 기본 연산을 제공 합니다. 문자열 의 시작 부분에서만match 일치 를 확인 하고 문자열의 어느 곳에서나 일치 를 확인 합니다 (기본적으로 Perl이 수행하는 작업).search

참고 match다를 수 있습니다 search 로 시작하는 정규 표현식을 사용하는 경우에도이 '^': '^'는 문자열의 시작과 일치, 또는에서 MULTILINE모드 즉시 줄 바꿈을 다음과 같습니다. 은 " match"작업이 성공 상기 경우에만 패턴 일치를 시작 문자열의 모드에 관계없이, 또는 옵션에 의해 지정된 시작 위치에서 pos 줄 바꿈 선행 여부에 관계없이 인수입니다.

이제 충분히 이야기하십시오. 예제 코드를 볼 시간입니다.

# example code:
string_with_newlines = """something
someotherthing"""

import re

print re.match('some', string_with_newlines) # matches
print re.match('someother', 
               string_with_newlines) # won't match
print re.match('^someother', string_with_newlines, 
               re.MULTILINE) # also won't match
print re.search('someother', 
                string_with_newlines) # finds something
print re.search('^someother', string_with_newlines, 
                re.MULTILINE) # also finds something

m = re.compile('thing$', re.MULTILINE)

print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines, 
               re.MULTILINE) # also matches

줄 바꿈이 포함 된 문자열은 어떻습니까?
Daryl Spitzer

26
그렇다면 왜 match더 일반적인 것이 아니라 제한된 것을 사용 search합니까? 속도입니까?
Alby

13
@Alby match는 검색보다 훨씬 빠르므로 regex.search ( "word") 대신 regex.match ((. *?) word (. *?))를 수행하고 작업하는 경우 엄청난 성능을 얻을 수 있습니다 수백만 개의 샘플.
ivan_bilan

20
글쎄, 그건 바보입니다. 왜 전화 해 match? 직관적이지 않은 이름으로 API를 파종하여 문서를 읽도록하는 것이 현명한 방법입니까? 나는 아직도 그것을하지 않을 것입니다! 반역자!
Sammaron

1
@ivan_bilan matchfaster동일한 정규 표현식을 사용할 때 검색보다 약간 보이지만 성능 테스트에 따라 예제가 잘못 보입니다 : stackoverflow.com/questions/180986/…
baptx

101

search ⇒ 문자열의 어느 곳에서나 무언가를 찾아서 일치하는 객체를 반환합니다.

match⇒ 문자열 의 시작 부분 에서 무언가를 찾아서 일치하는 객체를 반환합니다.


49

re.search 검색 패턴에 대한 ES를 문자열에 걸쳐 반면 re.match않는 검색하지 패턴을; 그렇지 않은 경우 문자열 시작시 일치 하는 것 외에 다른 선택이 없습니다 .


5
시작시 일치하지만 문자열 끝까지 일치하지 않는 이유는 무엇입니까 ( fullmatchphyton 3.4에서)?
Johnth

49

일치하는 것이 검색보다 훨씬 빠르므로 regex.search ( "word") 대신 regex.match ((. *?) word (. *?))를 수행하고 수백만의 작업을 수행하는 경우 엄청난 성능을 얻을 수 있습니다 견본.

위의 허용 된 답변 아래 @ivan_bilan 의이 의견은 그러한 이 실제로 속도를 높이고 있는지 실제로 생각 합니다. 그래서 실제로 얼마나 많은 성능을 얻을 수 있는지 알아 보겠습니다.

다음 테스트 스위트를 준비했습니다.

import random
import re
import string
import time

LENGTH = 10
LIST_SIZE = 1000000

def generate_word():
    word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
    word = ''.join(word)
    return word

wordlist = [generate_word() for _ in range(LIST_SIZE)]

start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)

start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)

10 가지 측정 (1M, 2M, ..., 10M 단어)을 수행하여 다음 플롯을 얻었습니다.

일치 대 검색 정규식 속도 테스트 선 그림

결과 라인은 놀랍게도 (실제로는 그렇게 놀랍지 않습니다) 직선입니다. 그리고이 특정 패턴 조합이 주어지면 search기능이 (약간) 빠릅니다 . 이 테스트의 교훈 : 코드를 과도하게 최적화하지 마십시오.


12
액면가에 반영 될 진술의 가정을 실제로 조사한 결과 +1-감사합니다.
Robert Dodier

실제로 @ivan_bilan의 의견은 잘못 보이지만 동일한 정규 표현식을 비교하면 함수 match보다 함수가 여전히 빠릅니다 search. 당신은 비교하여 스크립트에서 확인하실 수 있습니다 re.search('^python', word)re.match('python', word) (또는 re.match('^python', word)당신이 문서를 읽을 수없는 경우 이해하기가 동일하지만, 쉽게 및 성능에 영향을 미치지 않도록 보인다)
baptx

@ baptx 나는 match기능이 일반적으로 더 빠르다는 진술에 동의하지 않는다 . (가) match검색 할 때 빠른 시작 부분에 문자열의의는 search검색 할 때 빠른 걸쳐 문자열. 상식에 해당합니다. 그래서 @ivan_bilan이 잘못되었습니다. 그는 match문자열 전체를 검색 하는 데 사용 했습니다. 그렇기 때문에 당신이 옳습니다-당신 match은 문자열의 시작 부분에서 검색 하는 데 사용했습니다 . 당신이 저에게 동의하지 않는다면, match그 정규식을 찾는 것이 더 빠르며 re.search('python', word)같은 일 을 한다는 것을 찾으십시오 .
Jeyekomon

각주로, 또한 @baptx 상기는 re.match('python') 이고 빠르게보다 근소 re.match('^python'). 그건 그래야만 해.
Jeyekomon

@Jeyekomon 예, 그것이 의미하는 바입니다 match. 문자열의 시작 부분에서 검색하려는 경우 함수가 약간 빠릅니다 (예 : search함수를 사용하여 문자열의 시작 부분에서 단어를 찾는 것과 비교 re.search('^python', word)). 그러나이 이상한 것을 발견했습니다 search. 문자열의 시작 부분에서 검색 하도록 함수에 지시 하면 함수만큼 빠릅니다 match.
baptx

31

아래 예제를 참조하여 re.match재검색 작업을 이해하십시오 .

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match 돌아올 것이다 none 하지만 re.search반환 abc합니다.


3
검색에 _sre.SRE_Match 객체 (또는 찾을 수없는 경우 없음)가 반환되도록 추가하고 싶습니다. 'abc'를 얻으려면 t.group ()
SanD

30

차이점은 Perl , grep 또는 sed 정규 표현식 일치에 re.match()익숙한 사람을 오도 하고 그렇지 않은 것입니다. re.search():-)

더 진지하게, 존 D. 쿡 발언 , re.match()"모든 패턴이 ^ 앞에 추가 한 경우로 동작합니다." 다시 말해, re.match('pattern')같습니다 re.search('^pattern'). 따라서 패턴의 왼쪽을 고정합니다. 그러나 패턴의 오른쪽을 고정하지는 않습니다$ . 여전히 종료가 필요합니다 .

솔직히 위에서 말하면, 나는 re.match()더 이상 사용되지 않아야 한다고 생각 합니다. 그것이 유지되어야하는 이유를 알고 싶습니다.


4
"모든 패턴이 앞에 붙은 것처럼 동작합니다." 여러 줄 옵션을 사용하지 않는 경우에만 해당됩니다. 정답은 "...가 \ A 앞에
붙었다

14

re.match는 문자열의 시작 부분에서 패턴을 일치 시키려고 시도 합니다 . re.search는 일치하는 것을 찾을 때까지 문자열 전체 에서 패턴을 일치시킵니다 .


3

훨씬 더 짧은 :

  • search 전체 문자열을 스캔합니다.

  • match 문자열의 시작 부분 만 스캔합니다.

Ex가 다음과 같이 말합니다.

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.