Python 정규식과 백슬래시 충돌 문제
정규식(regular expression)은 백슬래시 문자('\')를 사용하여 특수한 형태를 표현하거나, 특수 문자가 지닌 특별한 의미를 해제하고 일반 문자로 취급하도록 합니다. 그런데 여기서 문제가 발생합니다. Python은 문자열 리터럴(string literal) 안에서도 같은 목적으로 동일한 백슬래시 문자를 사용하기 때문입니다.
예를 들어, 정규식으로 리터럴 백슬래시 하나를 매칭하려면 어떻게 해야 할까요? 정규식 엔진 입장에서는 패턴이 \\여야 하고, 일반 Python 문자열 리터럴 안에서 각 백슬래시는 다시 \\로 표현해야 하므로, 결국 패턴 문자열을 '\\\\'처럼 작성해야 합니다. 백슬래시가 네 개나 들어가는 것입니다.
해결 방법 1: Raw String(원시 문자열) 표기법
이 문제에 대한 가장 권장되는 해결책은 Python의 raw string(원시 문자열) 표기법을 사용하는 것입니다. 문자열 앞에 r을 붙이면 해당 문자열 내부의 백슬래시는 어떠한 특수 처리도 받지 않습니다.
r"\n"→ 두 글자짜리 문자열 ('\'와 'n')"\n"→ 한 글자짜리 문자열 (줄바꿈 문자)
따라서 실무에서는 정규식 패턴을 작성할 때 거의 항상 raw string 표기법을 사용하는 것이 좋습니다.
import re
# 일반 문자열 사용 시
pattern1 = "\\d+" # 숫자 매칭
# raw string 사용 시 (권장)
pattern2 = r"\d+" # 훨씬 읽기 쉽고 직관적
result = re.findall(pattern2, "abc123 def456")
print(result) # ['123', '456']해결 방법 2: re.escape() 함수 활용
사용자 입력값처럼 내용을 예측할 수 없는 문자열을 정규식 패턴에 포함해야 하는 경우에는 re.escape() 함수를 사용하면 편리합니다. 이 함수는 문자열 안의 모든 특수 문자를 자동으로 이스케이프 처리해 줍니다.
import re
user_input = "3.14 (특수문자 포함)"
safe_pattern = re.escape(user_input)
print(safe_pattern) # '3\.14\ \(특수문자\ 포함\)'
match = re.search(safe_pattern, "결과값은 3.14 (특수문자 포함) 입니다")
if match:
print("매칭 성공!", match.group())정리
Python 정규식에서 특수 문자를 이스케이프할 때 기억해야 할 핵심은 다음과 같습니다.
- 백슬래시는 정규식과 Python 문자열 양쪽에서 모두 특수 의미를 가지므로 충돌이 발생할 수 있습니다.
- 패턴 작성 시에는
r접두사가 붙은 raw string을 사용하면 이중 이스케이프 문제를 피할 수 있습니다. - 동적인 문자열을 패턴에 넣어야 한다면
re.escape()로 자동 이스케이프 처리하세요.