프로그래밍/python

파이썬 정규 표현식 match, search 함수, group

콘파냐 2017. 3. 23. 07:03
반응형

앞서 파이썬에서 정규표현식을 어떻게 사용하는지 간단하게 살펴보았다. findall 함수를 사용하였는데 이 함수 외에도 검색을 위한 match, search함수가 있다. 또, 검색된 패턴을 다른 문자열로 치환해주는 sub 함수도 있다. 우선 여기서는 match, search만 살펴볼 것이다. 

우선 앞서 다루었던 findall 함수의 특색을 살펴보자. 이 함수는 겹치지 않는 매칭을 모두 찾는다는 특징이 있다 겹치지 않는다는 의미는 다음과 같은 것이다. 

이렇게 findall 함수는 찾는 문자열 간에 겹치지 않도록 모든 문자열들을 찾는다. 그리고 찾는 문자열들을 리스트로 반환해 주는 특징이 있다. 이제 설명할 match함수와 search함수는 찾는 방식도 findall함수와 차이가 있지만 반환하는 값도 차이가 있다. 이 두 함수는 리스트가 아닌 MatchObject라는 객체를 반환하는데 이 것을 이용해서 찾은 값들을 처리한다.


match


match함수는 (원본)문자열의 시작부분부터 패턴과 매칭이 되는지 검사한다. 문자열 중간에 찾을 패턴이 있더라도 match함수는 시작부터 패턴이 일치되지 않으면 찾지 않는다. IDLE에서 예제를 실행해 보자.

>>> import re
>>> string = "lololo"
>>> re.match("olo", string)
>>>

위와 같이 match 함수로 "olo"라는 문자열 패턴을 찾았지만 아무런 반환값이 없다. 이것은 None을 반환했다는 의미고 아무런 패턴을 찾지 못했다는 의미다. 반면에 findall을 사용해서 같은 작업을 수행하면 하나의 "olo"를 찾을 것이다.

이번에는 "lol"을 찾아보자.

>>> re.match("lol", string)
<_sre.SRE_Match object; span=(0, 3), match='lol'>

반환되는 Match object라는 객체가 생겼고 매칭 정보까지 표시해 주고 있다. 이 객체에서 매칭된 값을 얻으려면 group라는 메서드를 사용하면 된다.

>>> re.match("lol", string).group()
'lol'

group에 대해서는 나중에 다시 언급하고 이번에는 search메소드를 살펴보자.


search


이 메소드는 처음부터 검사해 나가지만 매칭되는 패턴이 있다면 더이상 추가적인 검사를 하지 않는다. 나머지 특징은 match함수와 같다.

>>> string = "lololololololol"
>>> re.search("olo", string).group()
'olo'


그렇다면 group이 뭘까?


group


비유적인 표현을 하자면 이렇다. 산에서 감자를 캐는 사람이 있다고 하자. 그런데 이 사람은 주면에 쑥이 나는 곳에서 발견한 감자만 캔다고 한다. 그렇다면 이 사람은 이렇게 패턴을 검사할 것이다. 

쑥이 나는 곳을 찾고 그 곳에 감자도 있다면 감자를 찾아서 캔다. 하지만 쑥은 캐지 않는다.

패턴은 쑥이나는 곳에 있는 감자를 찾는 것이다. 하지만 이 사람은 감자만 캔다. 쑥은 단지 패턴 검사용일 뿐이다.

앞에서 우리가 group()을 호출했을 때는 쑥이나는 곳에 있는 감자와 같이 우리가 처음 설정해 놓은 패턴을 말한다. 그리고 다음과 같이 감자를 캘 수 있다.

>>> string = "Dpotato1 potato2 Fpotato3 SSpotato4 potato5"
>>> re.findall("[S]{2}potato\d", string)
['SSpotato4']

쑥을 "SS"로 표현했다. findall 함수로 위 패턴을 찾았지만 우리가 캐려는 것은 "potato4"다 그렇다면 그룹을 지어주면 된다.

>>> re.findall("[S]{2}(potato\d)", string)
['potato4']

단지 우리가 캐려는 감자에 해당하는 패턴에 (감자패턴) 소괄호를 해 주었다.

이런 그룹화는 여러개를 할 수도 있다. 우선 search함수에서 동일한 검색을 해보도록 하겠다.

>>> re.search("[S]{2}(potato\d)", string).group()
'SSpotato4'
>>> re.search("[S]{2}(potato\d)", string).group(1)
'potato4'

group()는 쑥이 있는 곳의 감자를 의미하고 group(1)은 패턴 중에서 첫 번째 그룹지은 패턴을 의미한다.(여기에서는 감자가 되겠다.) 만약 그룹을 여러개 지었다면 순서대로 group(1), group(2), .... 이렇게 결과를 반환할 수 있다.

반응형