python 정규식 사용법


python 정규식 사용법에 대해서 아는대로 포스팅 합니다.

정규식은 보통 정규 표현식이라고도 이야기 되며

파이썬에서만 쓰는 것이 아닌, 프로그래밍에서 문자열을 다룰 때

일정한 패턴을 표현하는 일정의 형식 언어이다.

파이썬에도 있고 sql에서도 사용이 가능하며

다른 언어들에서도 사용이 가능하다.

그렇기에, 이번 포스팅에서는 정규식의 기본 내용과

파이썬에서 활용하는 방법을 소개하고자 한다.


1.정규식 기초

정규식에서 숫자만 가져오는 방법, 영 문자만 가져오는 방법을 주로 봤다면

[0-9] 혹은 [a-zA-Z]를 봤을 것이다.

이러한 [] 안에는 가능한 문자열들을 지정할 수 있고 “-“ 를 통해서 범위 지정도 가능하다.


이렇게 직접 설정도 가능은 하지만, 기본적으로 \을 활용한 별도 표기법으로

간단하게 바로 사용이 가능하다.

\d : 숫자와 매칭 [0-9] 와 동일

\s : whitespace(공백문자) 와 동일

\w : 문자 + 숫자 + _(밑줄문자)와 동일 [a-zA-Z0-9_]

+ 해당 \ 뒤에 문자를 대문자로 바꾸면 여집합으로 취급됨

ex) \D : 숫자 이외 문자 [^0-9]

여기서 \d, \D의 차이를 보면 ^가 있는데 이러한 문자들도 정규식에서 중요하게 사용된다.


^ : 문자열의 시작

[ ] : 가능한 문자열들의 집합 나열 가능

[ - ] : 문자열들 사이에 범위 지정 가능 (ex [a-z] 소문자 a 부터 z까지 = 영어 소문자만 확인)

[^ ] : 가능한 문자열들의 여집합으로 사용 (ex [^a-z] = 영어 소문자 제외한 전 문자)

| : or 기능

( ) : 괄호 안의 정규식을 그룹으로 만듦

. : \n을 제외한 모든 문자와 매치됨 ex) a.b -> a0b(가능), aab(가능), abc(해당 없음)

이러한 괄호와 특수 기호들을 활용하여 정규식을 사용이 가능하다.

그리고 가장 핵심 적인 것이 문자의 갯수를 지정할 수 있는 것이다.


* : 문자가 0회 이상 반복

+ : 문자가 1회 이상 반복

? : 문자가 0 or 1회 반복

{m} : 문자가 m회만 반복

{m, n} : 문자가 m회 이상 n회 이하 까지 반복

{m, } 문자가 m회 이상 반복

이러한 문자들을 메타문자라고 표현하며,

이러한 방식으로 자주 보여지는 예시가 있는데 전화 번호를 찾는 방법이다.

일반 휴대폰 번호를 찾기 위해서는 보통 [0-9]{3}-[0-9]{3,4}-[0-9]{3,4}를 사용한다.

해석하자면 3자리 번호 + -(특수문자) + 3 or 4자리 번호 + -(특수문자) + 3 or 4자리 번호 를 찾는 방법이다.


2.파이썬 정규식 기초와 주석 사용

파이썬에서는 re라는 라이브러리로 정규식 사용이 가능하다.

바로 위의 예시를 찾는 방법을 파이썬 코드로 작성 하였습니다.

import re

text = "문의사항이 있으면 000-000-0000 혹은 000-0000-0000 으로 연락주시기 바랍니다."

regex = re.compile(r'[0-9]{3}-[0-9]{3,4}-[0-9]{3,4}')

regex.findall(text)
['000-000-0000', '000-0000-0000']

compile 안에서 맨 처음에 붙는 r은 raw string임을 나타내기 위한 표시이다.

re.compile로 원하는 정규식 형태를 지정을 해주고

findall을 사용하여, 해당 정규식 형태에 해당 되는 문자들을 전부 가져오도록 하였다.


당장 이렇게만 되어있으면 바로 사용할 때는 이해하기가 쉽지만

나중에 까먹거나 다른 사람이 봤을때 힘들수 있는 경우가 생긴다.

그렇기에 정규식에는 주석을 달 수 있는 방법이 있다.

regex = re.compile(r'''
[0-9]{3}-    #핸드폰 앞자리 3자리
[0-9]{3,4}-    #핸드폰 중간 번호(3~4자리)
[0-9]{3,4}    #핸드폰 끝번호(3~4자리)
''', re.VERBOSE)

regex.findall(text)
['000-000-0000', '000-0000-0000']

’'’은 한 줄 짜리가 아닌 여러 줄을 하기 위해서 하는 것이고

같은 정규식이지만 쉼표 뒤에 re.VERBOSE를 사용하면

정규식 내에 있는 whitespace는 사라지고( []안에 있는 공백은 관련 없음 )

줄 단위로 # 기호를 사용하여서 주석을 달 수 있게 된다.


3.파이썬 정규식 문자열 검색

위에서 소개한 findall은 정규식과 매치되는 모든 문자를 모두 list로 반환한다

비슷하게 find는 맨 처음 결과 하나만 반환한다.

match는 문자열 처음부터 비교하여 정규식과 동일한지 찾아주고

search는 문자열 전체를 비교 후, 정규식과 매치되는 첫 결과를 반환해준다.

findier는 finall과 동일하지만 iterator 형태로 반환해준다.


p = re.compile('[a-z]+')

m = p.match("python")
print(m)
<re.Match object; span=(0, 6), match='python'>
m = p.match("3 python")
print(m)
None
m = p.search("3 python")
print(m)
<re.Match object; span=(2, 8), match='python'>
result = p.finditer("life is too short")
print(result)
<callable_iterator object at 0x000001E87C8DB5E0>
for r in result:
    print(r)
<re.Match object; span=(0, 4), match='life'>
<re.Match object; span=(5, 7), match='is'>
<re.Match object; span=(8, 11), match='too'>
<re.Match object; span=(12, 17), match='short'>


이렇게 match, search 등으로 나온 결과를 보면

해당 문자열의 시작, 끝 위치 그리고 해당 문자가 나오는데

이러한 것들을 바로 출력을 해주는 것이 있다.

.group()은 매치된 문자열을 반환하고

.start(), .end(), .span()은

각각 문자열의 시작 위치, 끝 위치, (시작, 끝) 튜플을 반환 한다.


4.파이썬 정규식 문자열 치환 방법

특정 패턴에 대한 문자를 찾는 방법이 있기에,

정규식에는 특정 패턴 문자를 변환시키는 방법 또한 존재한다.

re.sub(pattern='원하는 패턴', repl='변환후 문자', string = '문자열', count = 최대 숫자)

적용 방식은 replace와 동일하고 pattern= 등은 생략이 가능하지만,

생략할 경우에 순서를 잘 지정하여야 한다.

count는 최대 변환하고자 하는 갯수이며

만약 찾은 패턴이 3개인데, count가 2인 경우라면 앞에서부터 최대 2개만 변환 시키고 이를 반환한다.