이 글은 도서 '점프 투 파이썬' 연습문제를 토대로 작성하였습니다.
정규 표현식(Regular Expressions) 은 복잡한 문자열을 처리할 때 사용하는 기법으로 문자열을 처리하는 모든 곳에서 사용한다. 줄여서 정규식 이라고도 한다.
정규 표현식에서 사용하는 메타문자(meta characters)에는 다음과 같은 것들이 있다.
메타문자 : 원래 그 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자를 말한다.
. ^ $ * ? {} [] \ | ()
메타문자의 사용법을 알아보자
문자 클래스[] 는 문자클래스로 만들어진 정규식은 [] 사이의 문자들과 매치
라는 의미를 갖는다. 즉 정규표현식이 [abc]
라면 이 표현식의 의미는 a,b,c중 한 개의 문자와 매치를 뜻한다. 이해를 돕기 위해 문자열 "a","before","dude"가 정규식 [abc]
와 어떻게 매치되는지 살펴보자.
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
[abc] | a | yes | "a"는 정규식과 일치하는 문자인 "a"가 있으므로 매치 |
[abc] | before | yes | "before"는 정규식과 일치하는 문자인 "b"가 있으므로 매치 |
[abc] | dude | no | "dude"는 a,b,c 중 하나도 포함하고 있지 않으므로 매치되지 않음 |
[]
안의 두 문자 사이에 하이픈(-)을 사용하면 두 문자 사이의 범위(from-to)를 의미한다.
ex) [a-c] = [abc] , [0-5] = [012345]
메타 문자 ^
는 문자 클래스안에 사용할 경우 반대(not)의 의미를 갖는다. 예를 들어 [^0-9]라는 정규식은 숫자가 아닌 문자만 매치된다.
[0-9],[a-zA-Z]는 자주 사용하는 정규식이다. 자주 사용하는 정규식은 별도의 표기법으로 나타낼 수 있다.
정규 표현식 | 설명 |
---|---|
\d | 숫자와 매치,[0-9]와 동일한 표현이다. |
\D | 숫자가 아닌 것과 매치, [^0-9]와 동일한 표현이다. |
\s | whitespace문자(공백을 표현하는 문자), [\t\n\r\f\v]와 동일한 표현식이다. |
\S | [^\t\n\r\f\v]과 동일한 표현식이다. |
\w | 문자+숫자와 매치, [a-zA-Z0-9]와 동일한 표현식이다. |
\W | [^a-zA-Z0-9]와 동일한 표현식이다. |
Dot(.)
정규표현식의 Dot(.)
메타 문자는 줄바꿈 문자인 \n
을 제외한 모든 문자와 매치됨을 의미한다.
a.b
정규식을 살펴보자. 줄바꿈 문자를 제외한 어떠한 문자가 들어와도 모두 매치된다.
a + 모든 문자 + b
와 같은 의미이다. 아래 표를 통해 더 알아보자.
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
a.b | aab | yes | "aab"는 가운데 문자 "a"가 모든 문자를 의미하는 .과 일치하므로 정규식과 매치 |
a.b | aOb | yes | 문자 "O" 가 모든 문자에 해당하므로 매치 |
a.b | abc | no | "abc"는 "a"문자와 "b"문자 사이에 문자가 없기 때문에 매치되지 않음 |
a[.]b
정규식a[.]b
= "a + Dot(.)문자 + b"
문자 클래스 []안에 . 이 들어가 있다면 이것은 Dot(.)의 의미가 아니라 문자 그대로의 .을 의미한다. 이것을 조심해서 보도록하자.
메타 문자 *
: 바로 앞에 있는 문자가 0부터 무한대로 반복될 수 있다는 의미.
다음 예시를 살펴보자.
ex) ca*t
# *문자 바로 앞에 있는 a가 0번 이상 반복되면 매치
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
ca*t | ct | yes | "a"가 0번 반복되어 매치 |
ca*t | cat | yes | "a"가 0번 이상 반복되어 매치(1번 반복) |
ca*t | caaat | yes | "a"가 0번 이상 반복되어 매치(3번 반복) |
메타 문자 +
: +는 최소 1번 이상 반복될 때 사용한다.
다음 예시를 살펴보자
ex) ca+t
#문자 바로 앞에 있는 a가 1번 이상 반복되면 매치
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
ca+t | ct | no | "a"가 0번 반복되어 매치되지 않음 |
ca+t | cat | yes | "a"가 1번 이상 반복되어 매치(1번 반복) |
ca+t | caaat | yes | "a"가 1번 이상 반복되어 매치(3번 반복) |
메타 문자 {}
: 반복횟수를 고정할 때 사용 반복 횟수를 m~n까지 고정할 수 있다.
ca{2}t
# a가 2번 반복되면 매치
ca{2}t
= c + a(반드시 2번 반복)+ b
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
ca{2}t | cat | no | "a"가 1번 반복되어 매치되지 않음 |
ca{2}t | caat | yes | "a"가 2번 반복되어 매치 |
ca{2,5}t
# a가 2~5번 반복되면 매치
ca{2,5}t
= c +a(2~5번 반복) + t
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
ca{2,5}t | cat | no | "a"가 1번 반복되어 매치되지 않음 |
ca{2,5}t | caat | yes | "a"가 2번 반복되어 매치 |
ca{2,5}t | caaaaat | yes | "a"가 5번 반복되어 매치 |
메타 문자 ?
= {0, 1}
ab?c
= a + b(있어도 되고 없어도 된다) +c
# b가 0~1번 사용되면 매치
정규식 | 문자열 | 매치여부 | 설명 |
---|---|---|---|
ab?c | abc | yes | "b"가 1번 사용되어 매치 |
ab?c | ac | yes | "b"가 0번 사용되어 매치 |
파이썬은 정규 표현식을 지원하기 위해 re(regular expression) 모듈을 제공한다. re모듈은 파이썬을 설치할 때 자동으로 설치되는 기본 라이브러리로 사용방법은 다음과 같다.
import re
p = re.compile('ab*')
re.compile
을 사용해 정규식을 컴파일한다.re.compile
의 결과로 돌려주는 객체 p
(컴파일된 패턴 객체)를 사용하여 그 이후의 작업을 수행할 것이다.
메서드 | 목적 |
---|---|
match() | 문자열의 처음부터 정규식과 매치되는지 조사 |
search() | 문자열 전체를 검색하여 정규식과 매치되는지 조사 |
findall() | 정규식과 매치되는 모든 문자열을 리스트로 반환 |
finditer() | 정규식과 매치되는 모든 문자열을 반복 가능한 객체로 반환 |
검색 메서드를 사용하기 위해서는 다음과 같은 코드를 작성한다.
import re
p = re.compile(정규식)
m = p.match/search/findall/finditer(조사할 문자열)
print(m) # m이라는 객체에 대입
메서드 | 목적 |
---|---|
group() | 매치된 문자열을 돌려준다 |
start() | 매치된 문자열의 시작 위치를 돌려준다 |
end() | 매치된 문자열의 끝 위치를 돌려준다 |
span() | 매치된 문자열의(시작, 끝)에 해당하는 튜플을 돌려준다. |
match 객체의 메서드 사용 방법을 살펴보자.
import re
p = re.compile('[a-z]+')
m = p.match("python")
print(m.group()) # 'python'
print(m.start()) # 0
print(m.end()) # 6
print(m.span()) # (0, 6)
만약 search를 사용했을 때 차이점을 살펴보자.
import re
p = re.compile('[a-z]+')
m = p.search("3 python")
print(m.group()) # 'python'
print(m.start()) # 2
print(m.end()) # 8
print(m.span()) # (2, 8)
옵션 이름 | 약어 | 설명 |
---|---|---|
DOTALL | S | dot문자(.)가 줄바꿈 문자를 포함하여 모든 문자와 매치 |
IGNORECASE | I | 대,소문자와 관계 없이 매치 |
MULTILINE | M | 여러 줄과 매치(^,$ 메타 문자 사용과 관계 있음) |
VERBOSE | X | verbose 모드를 사용(정규식을 보기 편하게 하고 주석 사용 가능) |
만약 \section
이라는 문자열을 찾는다고 가정해보자. 이 문자열은 \s
가 whitespace 로 해석되어 의도한 대로 매치가 이루어지지 않는다.
\section
= [\t\n\r\f\v]ection
둘은 동일한 의미이다.
의도한 대로 문자열을 조사하고 싶으면 \\section
으로 변경해야한다.
하지만 파이썬에서 이렇게 사용할 경우 파이썬 문자열 리터럴 규칙에 따라 \\
이 \
으로 자동으로 변경된다. 이처럼 파이썬에서 \\
문자를 전달하려면 \\\\
백슬래시 4개를 사용해야한다.
하지만 백슬래시를 4개나 사용하는 것은 코드 줄이 길어질 경우 가독성과 효율이 떨어질 수 있다.
이를 해결하기 위해 파이썬에서는 Raw String
규칙이 생겨나게 되었다.
즉 컴파일해야하는 정규식이 Raw String
임을 알려 줄 수 있도록 파이썬 문법을 만든 것이다.
p = re.compile(r'\\section')
정규식 문자열 앞에 r
문자를 삽입하면 정규식은 Raw String
규칙에 의하여 백슬래시 2개 대신 1개만 써도 2개를 쓴 것과 동일한 의미를 갖는다.