정규표현식(Regular Expression)은 문자열 속에서 특정한 패턴을 가진 문자열을 찾을 때 사용하는 것이다.
파이썬에서는 re
모듈을 통해 정규표현식을 제공한다. 그리고 주로 사용하는 4가지 메소드가 다음과 같다. 메소드의 파라미터가 각각 의미히는 것은 정규표현식, 찾을 문자열, 옵션이다.
Hello World
라는 문자열에서 문자 o
를 찾는다고 가정해보자.
import re
# 찾을 문자열
string = 'Hello World'
# 정규표현식
pattern = 'o'
result = re.findall(pattern, string)
print(result)
# 출력 결과는 ['o', 'o']
출력되는 결과는 두 개의 문자를 찾아낸다. 여기서 정규표현식을 ab
로 입력하면 해당하는 문자가 없다는 결과를 반환한다.
정규표현식에서 사용하는 메타 문자에는 아래와 같은 것들이 있다.
. ^ $ * + ? { } [ ] \ | ( )
이 중에서 대괄호는 대괄호 사이에 있는 문자들 중 매치되는 문자 하나를 찾는 것이다. 하이픈(-)을 사용하면 범위를 나타내는데, 예를 들어 소문자는 [a-z]
, 대문자는 [A-Z]
로 표현할 수 있다. 대소문자 전체는 [a-zA-Z]
로 표현하면 된다.
Hello World, 1 2 3 4 5
라는 문자열에서 소문자만 찾는다고 가정해보자.
import re
# 찾을 문자열
string = 'Hello World, 1 2 3 4 5'
# 정규표현식
pattern = '[a-z]'
result = re.findall(pattern, string)
print(result)
# 출력 결과는 ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']
결과는 총 8개의 소문자를 찾아냈다. 이외에도 [0-9]
로 표현하여 숫자 한 개를 찾아낼 수도 있다. 이처럼 대괄호는 사이에 존재하는 문자들 중 한 개를 찾아내는 것이다.
그렇다면 위에서 소개된 메타 문자를 찾고 싶을 땐 어떻게 할까? 프로그래밍을 조금 해보았다면 이스케이프 문자, 흔히 말하는 백슬래시(\
)를 사용하면 된다고 예상할 수 있다. 하지만 파이썬에서는 문자열 리터럴 규칙에 의해 백슬래시를 이스케이프 문자로 인식하기 때문에 백슬래시 문자열 그대로 인식하게 하려면 백슬래시를 두 번 사용해야 한다.
예를 들어, 대괄호 문자를 찾는다고 가정해보자. 이때는 정규표현식을 [\\[\\]]
이런 식으로 사용해야 한다. 파이썬 리터럴 규칙에 의해 [\[\]]
이렇게 인식이 되고, 이를 정규표현식에서는 백슬래시 뒤 대괄호를 문자 그대로 인식하여 최종적으로 [[]]
이와 같은 패턴이 되는 것이다.
역슬래시를 찾으려면 [\\\\]
이렇게 역슬래시를 네 번 입력해야 한다. 그래야 파이썬 리터럴 규칙에 의해 [\\]
로 인식되고, 정규표현식에 의해 최종적으로 [\]
패턴으로 인식한다.
문자열 !@#$%^&*()_+<>/\[]
에서 백슬래시와 대괄호를 찾아보도록 하자.
import re
# 찾을 문자열
string = '!@#$%^&*()_+<>/\[]'
# 정규표현식
pattern = '[\\\\\\[\\]]'
result = re.findall(pattern, string)
print(result)
# 출력 결과는 ['\\', '[', ']']
출력 결과를 보면 백슬래시는 파이썬에서 이스케이프가 필요하여 하나 더 붙었지만 대괄호는 그대로 출력되었다.
백슬래시를 여러 번 쓰는게 불편하여 파이썬에는 Raw String이라는 규칙이 생겼다. 이는 문자열 앞에
r
을 붙여 해당 문자열에서 사용하는 백슬래시는 문자열 그대로임을 나타낼 때 사용한다.
예를 들어, 위 패턴'[\\\\\\[\\]]'
은r'[\\\[\]]'
이렇게 백슬래시를 한 번만 사용해도 된다. 파이썬에서의 이스케이프 처리가 필요없는 문자열이라는 의미이다.
\w
: 특수 문자, 공백을 제외한 문자 한개를 찾을 때 사용한다.\W
: 특수 문자, 공백만 찾을 때 사용한다.^
) : [^a-z]
라는 정규표현식을 사용하면 소문자를 제외한 모든 글자 한 개를 찾는다. 즉, ^
뒤에 오는 문자를 제외한 문자를 찾을 때 사용한다.^
) : ^
뒤에 오는 문자가 문자열의 처음부분에 있는지 검사할 때 사용한다. ^[a-z]
는 문자열 처음에 소문자가 있는지 검사한다.$
) : $
앞에 있는 문자가 문자열의 마지막부분에 있는지 검사할 때 사용한다. [a-z]$
는 문자열 끝에 소문자가 있는지 검사한다..
) : 점은 공백을 포함한 모든 문자 한 개를 찾을 때 사용한다.+
문자는 한 개 이상의 문자가 반복되는지 검사한다. [a-z]+
는 한 개 이상의 소문자 문자열을 찾을 때 사용한다.
import re
# 찾을 문자열
string = 'Helo, World. !@#$%^&*()_+<>/\[]'
# 정규표현식
pattern = '[a-z]+'
result = re.findall(pattern, string)
print(result)
# 출력 결과는 ['elo', 'orld']
찾고자 하는 문자열 길이를 지정할 때 중괄호({}
)를 사용한다. [a-z0-9,]{3}
패턴은 소문자, 숫자, 쉼표가 세 개 일치하는 문자를 찾는 것이다.
import re
# 찾을 문자열
string = 'Helo, World. 1,2,3,4,5 !@#$%^&*()_+<>/\[]'
# 정규표현식
pattern = '[a-z0-9,]{3}'
result = re.findall(pattern, string)
print(result)
# 출력 결과는 ['elo', 'orl', '1,2', ',3,', '4,5']
중괄호 안에 숫자를 두 개 입력하면 최소, 최대길이를 의미하는 것이다. 예를 들어, [a-z0-9,]{3,6}
은 문자열의 최소 길이가 3, 최대 길이가 6인 문자열을 검색하는 패턴이다.
이 외에도 많은 정규표현식이 있지만 기본적인 규칙에 대해서만 다루었다. 프로젝트를 진행하다가 더 깊은 내용을 다루게 되면 그때 공부 겸 포스팅을 하도록 하겠다.