본문 바로가기
Computer/python

[Python] 정규표현식 : 패턴 겹치는 경우 모두 찾는 방법

by injeolmialmond 2021. 9. 6.

안녕하세요! 이 게시물에서는 파이썬에서 정규표현식을 사용할 때 유의해야 할 특성을 정리해보도록 하겠습니다.

 

파이썬으로 문자열을 다루다 보면 정규표현식을 사용하게 되는 경우가 많습니다.

정규표현식이란, 문자열 내에서 특정한 규칙을 찾는 문자열을 찾기 위해 사용하는 표현입니다.

파이썬에서는 기본적으로 're'라는 모듈을 통해서 정규표현식을 사용할 수 있도록 하고 있습니다.

 

그런데 이 모듈을 사용하면서, 생각처럼 잘 작동하지 않는 경험을 하실 수도 있을 텐데요,

re 모듈의 특성을 알고 나면 본인이 원하는대로 정규표현식을 사용할 수 있으리라 생각합니다!

 

Regular Expression HOWTO — Python 3.9.7 documentation

 

Regular Expression HOWTO — Python 3.9.7 documentation

Introduction Regular expressions (called REs, or regexes, or regex patterns) are essentially a tiny, highly specialized programming language embedded inside Python and made available through the re module. Using this little language, you specify the rules

docs.python.org

regex - What do 'lazy' and 'greedy' mean in the context of regular expressions? - Stack Overflow

 

What do 'lazy' and 'greedy' mean in the context of regular expressions?

What are these two terms in an understandable way?

stackoverflow.com

 

1. 'greedy'하다

: 전체 문자열 중, 해당 패턴을 만족하는 가장 긴 문자열을 반환합니다.

따라서 'hello'에서 'h.+l'을 매칭하려 한다면, 'hel' 대신 'hell'을 매칭합니다.

 

이러한 특성을 막기 위해서는 'lazy'하게 만들어주면 됩니다. ?(물음표) 표시를 추가하여, 'lazy'하게, 즉 가장 짧은 문자열을 반환하도록 만들어줍니다. 그렇지만 이 경우 'hel'만을 반환합니다. 

 

 

2. 가장 첫 매칭 문자열을 반환한다

이는 기본적으로 패턴을 만족하는 단 하나의 경우만 매칭하여 반환하기 때문입니다. match(), search()는 모두 하나의 경우만 반환합니다.

모든 경우를 다 얻고 싶을 때는 findall(), finditer()를 사용하면 됩니다.

그런데 'helhelhel'에서 'hel'을 찾는 경우, 세 번 모두 매칭이 되지만, 'hhhhhhhhh'에서 'hhh'를 찾는 경우, 7번 매칭이 되지 않고 3번만 매칭이 됩니다. 

 

3. 'consume'한다

: 전체 문자열 중, 해당 패턴을 만족하는 문자열을 찾으면, 그 부분은 이후 탐색에서 배제됩니다.

 

그렇다면, 패턴이 겹치는 경우에도 매칭을 하고 싶을 땐 어떻게 해야 할까요? 'consume'하지 않도록 만들면 됩니다. 전방탐색(lookahead assertion)을 사용합니다.

[정규식] 전후방 탐색 (tistory.com)

 

[정규식] 전후방 탐색

출처 : minsone.github.io/regex/regexp-lookaround 전방탐색과 후방탐색 원하는 문자를 검색하기 위하여 정규식을 사용하였지만 어디서부터 문자를 찾을지 정해야할때도 있습니다. 이때 전후방탐색(lookaroun

exhibitlove.tistory.com

python - How to find overlapping matches with a regexp? - Stack Overflow

 

How to find overlapping matches with a regexp?

>>> match = re.findall(r'\w\w', 'hello') >>> print match ['he', 'll'] Since \w\w means two characters, 'he' and 'll' are expected. But why do 'el' and 'lo' not match the regex? ...

stackoverflow.com

보통 전방탐색을 이용할 때, '문자열(?=패턴)'과 같은 형태로 사용합니다. '문자열'이 포함되어있고, 그 전방(오른쪽)에 바로 '패턴'이 붙어 있는 경우, '문자열'만을 반환하도록 만든 것입니다.

 

여기서 우리는 '문자열'부분을 생략하고, '(?=패턴)'의 형태로 사용할 것입니다. 반환되는 것은 길이가 0인 문자열이기 때문에, consume되는 문자열이 없이 그 다음으로 넘어갑니다.

 

 

 

 

댓글