본문 바로가기
코딩 이야기/파이썬(Python)

단도직입 파이썬(Python) – 정규식(Regular Expression) 1/2

by 아재코더 2021. 12. 17.
정규표현식

연습문제 풀이를 통해 저의 파이썬 학습 수준을 어느 정도 가늠할 수 있었고, 간단하게 실전용 파이썬 코딩도 진행해 보았습니다. 아직 갈 길이 멀었습니다. 많은 산을 넘고, 물도 건너야겠죠!!! 계속 파이썬을 접하다 보면 조금씩 나아지리라는 믿음을 다집니다!

오늘은 파이썬만의 고유 문법이 아닌 문자열을 처리하는 모든 곳에서 사용되는 정규 표현식(Regular Expressions : 정규식으로도 불립니다.)에 대해 살펴보겠습니다.(C, 자바, 자바스크립트 등에서도 적용 가능합니다.) 잠깐 훑어본 바로는 흡사 어셈블리어(Assembly Language)를 읽는 수준의 문법이 종종 사용됩니다. 문자열을 처리하는 표현식이다 보니 내용 이해가 어렵지 않은데 반해 효과적으로 사용하려면 암기가 필요할 수 있겠단 생각 듭니다. 우선 정규식에 사용되는 메타 문자(Meta Chatacter : 특정한 용도로 사용되는 문자)를 살펴봅니다.

 
. ^ $ * + ? { } [ ] \ | ( )

문자 클래스 [ ]

정규식 [abc] 라면 ‘a, b, c 중 한 개의 문자와 매치’를 뜻합니다.

정규식
문자열
매치 여부
설명
[ abc ]
a
Yes
정규식과 일치하는 'a'가 있으므로 매치
be
Yes
정규식과 일치하는 'b'가 있으므로 매치
deep
No
정규식과 일치하는 문자가 매치되는 문자가 없음

[ ] 안의 두문자 사이에 하이픈(-)을 사용하면 범위를 뜻합니다. 대소문자를 엄격히 구분하는 점 유의하세요~!

ex. [0-5] = [012345], [a-d] = [abcd], [A-D] = [ABCD], [a-zA-Z] = [알파벳 모두], [0-9] = [숫자 모두]

메타 문자 ^는 반대(not)을 의미합니다.

ex. [^0-9] = [숫자가 아닌 문자]

자주 사용하는 문자 클래스는 아래와 같습니다.

정규식
설명
\d
숫자와 매치, [0-9]와 동일
\D
숫자가 아닌 것과 매치, [^0-9]와 동일
\s
space 또는 tab처럼 공백을 표현하는 문자와 매치,[\t\n\r\f\v]와 동일
맨 앞의 빈칸은 공백문자(space)를 의미
\S
space 문자가 아닌 것과 매치, [^\t\n\r\f\v]와 동일
\w
모든 숫자+문자와 매치, [a-zA-Z0-9_]와 동일
\W
숫자+문자가 아닌 문자와 매치, [^a-zA-Z0-9_]

대소문자의 관계를 잘 살펴봅니다.(not의 관계입니다.)

DOT( . )

Dot( . ) 메타 문자는 줄바꿈 \n을 제외한 모든 문자와 매치됩니다.

a.b는 a와 b 사이 어떠한 문자나 숫자가 오더라도 매치됩니다. aab, a0b와는 매치되고, abc와는 매치가 되지 않습니다.(a와 b 사이 어떠한 문자 하나라도 있어야 매치됩니다.)

a[ . ] b는 a와 b 사이에 DOT( . ) 가 있어야 매치됩니다.

 

반복( * )

ca*t는 *의 바로 앞 문자가 0번 이상 반복되면 매치됩니다. ct, cat, caaaaat가 매치됩니다.(ct도 ‘a’가 0번 이상이기 때문에 매치!)

 

반복(+)

ca+t는 +의 바로 앞 문자가 1번 이상 반복되면 매치됩니다. cat, caaaaat는 매치가 되지만 ct는 ‘a’가 1번 이상 반복이 안되어 매치가 안 됩니다.

 

반복( {m, n} , ? )

또는 *는 상한 없는 반복이 허용되지만 { }는 하한과 상한을 정할 수 있습니다. {3, }은 3번 이상 반복의 의미, { ,3}는 3번 이하 반복을 의미합니다.

{m, n}을 사용하면 반복 횟수 구간을 설정할 수도 있습니다.

?의 경우 0번~1번을 의미합니다. ca?t라고 가정할 때, ct, cat는 매치가 되고, caat는 매치되지 않습니다.

{ m }는 m 값을 반복해야만 매치가 됩니다. 더 이상도 이하도 매치되지 않습니다.

+, *, ? 모두 {m, n}형태로 고쳐 쓸 수 있지만 간결한 정규식을 위해 +, *, ? 사용을 권장합니다.

 

파이썬에서 정규 표현식을 지원하기 위해 re 모듈을 기본으로 제공합니다. 별다른 설치 없이 import re로 호출됩니다. 정규식을 사용하여 문자열을 검색해 봅니다. 문자열 검색을 위한 4가지 메서드는 아래와 같습니다.

메서드
목적
match( )
문자열 처음부터 매치 여부 조사
search( )
문자열 전체를 검색하여 매치 여부 조사
findall( )
정규식과 매치되는 문자열을 리스트로 리턴
finditer( )
정규식과 매치되는 문자열을 반복 가능한 객체로 리턴

match, search는 매치가 없을 때 None을 돌려줍니다.

>>> import re

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

>>> m=p.match('python')

>>> print(m)

<re.Match object; span=(0, 6), match='python'>

이때 p를 컴파일된 패턴 객체라 하며, ‘python’이 담겨진 m에 패턴 객체 p 와 매치 여부를 조사하여 결과가 담긴 match 객체를 리턴합니다. (python 문자열은 [a-z]+ 정규식에 부합하므로 match 결과에 python이 담겨 있습니다.)

>>> m=p.match('Python')

>>> print(m)

None

객체 m에 입력된 'Python'이 [a-z]+ 정규식에 부적합하므로 None을 리턴합니다.

상기와 같은 형태로 코딩 가능합니다.

 

search는 match와 달리 문자열 전체를 조사합니다.

>>> m=p.search('Python')

>>> print(m)

<re.Match object; span=(1, 6), match='ython'>

대문자 ‘P’를 제외한 ‘ython’과 매치됩니다.

 

findall 메서드는 매치되는 문자열을 리스트로 돌려줍니다.

>>> m=p.findall('python is easy')

>>> print(m)

['python', 'is', 'easy']

 

finditer 메서드는 findall과 동일하지만 반복 가능 한 객체로 돌려줍니다.

>>> result = p.finditer('python is easy')

>>> print(result)

<callable_iterator object at 0x0055AF40>

>>> for r in result: print(r)

...

<re.Match object; span=(0, 6), match='python'>

<re.Match object; span=(7, 9), match='is'>

<re.Match object; span=(10, 14), match='easy'>

 

match 객체의 메서드에 대해 알아봅니다.

메서드
목적
group( )
매치된 문자열을 리턴
start( )
매치된 문자열의 시작 위치를 리턴
end( )
매치된 문자열의 끝 위치를 리턴
span( )
매치된 문자열의 (시작, 끝)에 해당하는 큐플을 리턴

 

>>> a=p.match('python')

>>> a.group()

'python'

>>> a.start()

0

>>> a.end()

6

>>> a.span()

(0, 6)

댓글