파이썬 기초 - 8장 정규표현식 | 2024 점프 투 파이썬
여러분, 안녕하세요! 👨🏫 오늘은 '점프 투 파이썬' 강의의 여덟 번째 시간, **'정규 표현식(Regular Expressions)'**에 대해 깊이 있는 이야기를 나눠볼까 합니다. 드디어 파이썬 코딩의 신세계로 진입하는 순간이군요! 🚀
만약 여러분에게 "수많은 문서 속에서 'a'로 시작하고 'b'로 끝나는 모든 단어를 찾아줘!"라고 누군가 부탁한다면, 어떻게 하시겠어요? 아마도 일일이 눈으로 찾아내거나 복잡한 코드를 짜야 할 겁니다. 하지만 정규 표현식이라는 마법 같은 언어를 사용하면, 이 복잡한 문제를 단 몇 줄의 코드로 해결할 수 있습니다. 🪄
정규 표현식은 단순히 파이썬에만 있는 특별한 문법이 아닙니다. 이것은 텍스트 편집기, 데이터베이스, 심지어 운영체제에까지 사용되는, 문자열의 패턴을 정의하는 범용적인 언어입니다. 이 글에서는 마치 숙련된 탐정처럼 정규 표현식의 세계를 꼼꼼하게 탐색하며, 복잡한 문자열 처리의 비밀을 파헤쳐 드릴게요. 🕵️♂️✨
정규 표현식, 왜 배워야 할까? 🧐
정규 표현식은 'RegEx' 또는 'RegExp'라고도 불리며, 문자열에서 특정 패턴을 찾고, 추출하고, 혹은 바꾸는 데 사용됩니다. 왜 이것을 배워야 할까요? 그 이유는 다음과 같습니다.
- 코드의 간결성: 복잡한 조건문과 반복문으로 가득 차 있던 문자열 처리 코드를 단 한 줄로 압축할 수 있습니다.
- 강력한 기능: 이메일 주소 형식 유효성 검사, 전화번호 추출, HTML 태그 제거 등 복잡한 패턴을 손쉽게 다룰 수 있습니다.
- 높은 효율성: 대용량의 텍스트 데이터에서 원하는 정보를 빠르게 찾아내는 데 최적화되어 있습니다.
예를 들어, 주민등록번호 뒷자리를 별표(*)로 바꾸는 작업을 생각해봅시다. 정규 표현식을 사용하지 않으면 조건문과 슬라이싱을 복잡하게 조합해야 하지만, 정규 표현식은 단 두 줄로 끝낼 수 있습니다. 이처럼 정규 표현식은 **'패턴'**에 집중하여 문제를 해결하는 강력한 도구입니다.
정규 표현식의 기본: 메타 문자 📝
정규 표현식을 이해하려면, 우선 **'메타 문자(Meta Characters)'**를 알아야 합니다. 메타 문자는 그 문자가 가진 본래의 뜻이 아니라, 특별한 의미를 가진 문자들입니다. 마치 일반 글자(문자)가 아니라 명령을 내리는 특수 키(메타)라고 생각하면 쉽습니다.
1. 문자 클래스 []
대괄호 [] 안에 들어가는 문자들이 매치되는지 확인합니다.
- [abc]: 'a', 'b', 'c' 중 한 문자와 매치됩니다.
- [a-zA-Z]: 모든 알파벳 대문자 또는 소문자와 매치됩니다.
- [0-9]: 모든 숫자와 매치됩니다. \d와 동일합니다.
- [^0-9]: 캐럿(^)이 맨 앞에 오면 '부정'의 의미를 가집니다. 즉, 숫자를 제외한 모든 문자와 매치됩니다.
2. 점(.)
줄바꿈 문자(\n)를 제외한 모든 한 문자와 매치됩니다.
- a.b: 'a'와 'b' 사이에 어떤 한 문자가 오는 경우(예: acb, a!b) 매치됩니다.
3. 반복 관련 메타 문자
- * (별표): 바로 앞 문자가 0번 이상 반복되는 경우와 매치됩니다.
- ca*t: 'ct', 'cat', 'caat' 등 'a'가 없거나 여러 번 반복되는 경우 모두 매치됩니다.
- + (플러스): 바로 앞 문자가 1번 이상 반복되는 경우와 매치됩니다.
- ca+t: 'cat', 'caat' 등 'a'가 최소 한 번 이상 반복되는 경우만 매치됩니다.
- ? (물음표): 바로 앞 문자가 0번 또는 1번 반복되는 경우와 매치됩니다. {0,1}과 동일합니다.
- {m, n} (중괄호): 바로 앞 문자가 최소 m번, 최대 n번 반복되는 경우와 매치됩니다.
- ca{2}t: 'caat'만 매치됩니다.
- ca{2,4}t: 'caat', 'caaat', 'caaaat'가 매치됩니다.
- ca{2,}t: 'a'가 2번 이상 반복되는 모든 경우와 매치됩니다.
4. 위치 관련 메타 문자
- ^ (캐럿): 문자열의 시작점과 매치됩니다.
- ^Life: 'Life is too short'와는 매치되지만, 'I love Life'와는 매치되지 않습니다.
- $ (달러): 문자열의 끝점과 매치됩니다.
- short$: 'Life is too short'와 매치됩니다.
- \b (단어 경계): 단어의 시작점이나 끝점에 매치됩니다.
- \bclass: 'class'라는 단어 자체와 매치됩니다. 'multiclass'의 'class'와는 매치되지 않습니다.
- \B (비 단어 경계): \b와 반대로, 단어의 경계가 아닌 곳과 매치됩니다.
5. 그 외 유용한 메타 문자
- | (파이프): OR 연산과 동일합니다. 'A|B'는 'A' 또는 'B'와 매치됩니다.
- () (소괄호): 그룹핑에 사용됩니다. 이 안에 있는 내용을 하나의 덩어리로 묶을 수 있습니다.
파이썬에서 정규 표현식 사용하기 🐍
파이썬에서는 re 모듈을 사용하여 정규 표현식을 다룹니다.
1. re.compile()
정규 표현식을 컴파일하여 **'패턴 객체'**를 만듭니다. 이렇게 하면 같은 패턴을 여러 번 사용할 때 훨씬 효율적입니다.
2. match() vs. search()
- match(): 문자열의 처음부터 정규식과 매치되는지 조사합니다. 처음부터 매치되지 않으면 None을 반환합니다.
- search(): 문자열 전체를 탐색하여 정규식과 매치되는 첫 번째 경우를 찾습니다.
import re
pattern = re.compile('apple')
text = 'I have an apple and a pear.'
m = pattern.match(text) # None (문자열 시작이 'apple'이 아님)
s = pattern.search(text) # <re.Match object> (전체에서 'apple'을 찾음)
if s:
print("찾았다!")
3. findall() vs. finditer()
- findall(): 매치되는 모든 문자열을 찾아 리스트(list) 형태로 반환합니다.
- finditer(): 매치되는 모든 문자열을 찾지만, **반복 가능한 객체(iterator)**를 반환합니다. 이 객체를 사용하면 대용량 데이터에서 메모리를 효율적으로 사용할 수 있습니다.
import re
text = '123 abc 456 def'
pattern = re.compile('\d+') # 숫자가 1번 이상 반복
found_list = pattern.findall(text) # ['123', '456']
print(found_list)
found_iter = pattern.finditer(text)
for match in found_iter:
print(match.group()) # '123', '456'을 하나씩 출력
4. 매치 객체 메서드
match()나 search()에 성공하면 **'매치 객체'**가 반환됩니다. 이 객체에는 매치된 결과에 대한 다양한 정보가 담겨 있습니다.
- group(): 매치된 문자열을 반환합니다.
- start(): 매치된 문자열의 시작 위치 인덱스를 반환합니다.
- end(): 매치된 문자열의 끝 위치 인덱스(미만)를 반환합니다.
- span(): 매치된 문자열의 시작과 끝 위치를 (시작, 끝) 형태의 튜플로 반환합니다.
5. 문자열 바꾸기: re.sub()
re.sub(pattern, replace, string) 메서드는 문자열에서 패턴과 일치하는 모든 부분을 다른 문자열로 바꿉니다.
import re
text = "전화번호: 010-1234-5678, 이메일: example@test.com"
# 전화번호 패턴을 찾아 '***-****-****'로 바꾸기
new_text = re.sub('\d{3}-\d{4}-\d{4}', '***-****-****', text)
print(new_text) # 출력: 전화번호: ***-****-****, 이메일: example@test.com
정규 표현식의 심화 개념 🧠
1. 그룹핑 ()
소괄호 ()를 사용하여 정규식의 일부를 하나의 그룹으로 묶을 수 있습니다.
- 그룹 참조: group(인덱스)를 사용하여 매치된 문자열 중 특정 그룹의 내용만 가져올 수 있습니다. group(0)은 전체 매치 결과를 의미합니다.
- 이름 있는 그룹: (?P<이름>...) 형식을 사용하면 그룹에 이름을 붙일 수 있습니다.
- 재참조: \1, \2와 같이 \와 숫자를 사용하여 앞에서 매치된 그룹을 다시 참조할 수 있습니다.
import re
text = "John Smith is a good person. Kim Smith is also nice."
pattern = re.compile(r'(\w+)\s+(Smith)') # 그룹 1: 이름, 그룹 2: 성
match = pattern.search(text)
if match:
print(match.group(1)) # 출력: John
print(match.group(2)) # 출력: Smith
2. 전방 탐색 (Lookaround) 🔎
전방 탐색은 패턴을 매치시키되, 결과 문자열에는 포함시키지 않는 기능입니다.
- 긍정형 전방 탐색 (?=...): ...에 해당하는 패턴이 나와야 매치됩니다. (예: .*(?=apple)는 'apple' 앞에 있는 모든 문자를 매치)
- 부정형 전방 탐색 (?!...): ...에 해당하는 패턴이 나오지 않아야 매치됩니다. (예: .*(?!apple)는 'apple'이 아닌 단어 앞의 문자를 매치)
3. 탐욕성(Greedy) vs. 비탐욕성(Non-Greedy) 🤯
정규 표현식의 반복 관련 메타 문자(*, +, {m,n})는 기본적으로 가장 긴 문자열을 매치하려는 '탐욕성'을 가집니다.
- a.*b는 a...b...b라는 문자열에서 a부터 가장 마지막 b까지 모두 매치합니다.
- ?를 추가하여 a.*?b와 같이 만들면, 가장 짧은 문자열을 매치하려는 **'비탐욕성'**을 가지게 됩니다.
정규 표현식 실전 활용 예제 💡
예제 1: 이메일 유효성 검사
import re
email_pattern = re.compile(r'^[a-zA-Z0-9+-\_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$')
emails = ["test@example.com", "invalid-email@", "name@domain.co.kr"]
for email in emails:
if email_pattern.match(email):
print(f"{email}은(는) 유효한 이메일입니다.")
else:
print(f"{email}은(는) 유효하지 않은 이메일입니다.")
- ^: 문자열 시작
- [a-zA-Z0-9+-\_.]+: @ 앞의 사용자명 부분
- @: @ 문자
- [a-zA-Z0-9-]+: @ 뒤의 도메인 이름
- \.: . 문자
- [a-zA-Z0-9-.]+: 도메인 최상위 부분
- $: 문자열 끝
예제 2: HTML 태그 제거하기
import re
html_text = "<p>이것은 **정규 표현식** 강의입니다.</p>"
# <...> 패턴을 찾아서 제거
clean_text = re.sub('<.*?>', '', html_text)
print(clean_text) # 출력: 이것은 **정규 표현식** 강의입니다.
- <.*>: 태그의 시작과 끝을 포함하는 패턴. *는 탐욕성을 가지므로, <p>...</b>와 같은 여러 태그를 한 번에 제거할 수 있습니다.
- <.*?>: 비탐욕성을 사용하여 <p>만 매치하고 다음 <...>를 다시 찾습니다.
마무리하며... ✍️
오늘은 파이썬의 꽃이라 불리는 정규 표현식에 대해 알아봤습니다.
- 정규 표현식은 복잡한 문자열 패턴을 간결하게 정의하는 언어입니다.
- re 모듈과 match, search, sub 같은 함수를 통해 파이썬에서 사용할 수 있습니다.
- 메타 문자를 조합하여 원하는 패턴을 자유자재로 만들 수 있습니다.
정규 표현식은 처음에는 어렵고 낯설게 느껴질 수 있지만, 익숙해지면 여러분의 코딩 생산성을 비약적으로 높여주는 최고의 무기가 될 것입니다. 🛠️ 모든 패턴을 외우려 하기보다는, 필요한 패턴을 그때그때 검색하며 익숙해지는 것이 중요합니다. 이제 여러분의 파이썬 코딩 여정에 힘찬 날개가 달렸으니, 더 높이, 더 멀리 날아오르세요! 🦅
'IT⦁영어⦁하자보수 > IT' 카테고리의 다른 글
| AI로 직격탄 맞은 미국의 현재 상황, 한국도 머지 않았다?, 손재권 (0) | 2025.09.23 |
|---|---|
| PDF 파일을 JPG 파일로 변환하는 툴 (1) | 2025.09.22 |
| 9. 파이썬 기초 - 7장 파이썬 날아오르기 [조코딩] (1) | 2025.09.20 |
| 8. 파이썬 기초 - 6장 파이썬 프로그래밍 어떻게 시작해야 할까 [조코딩] (0) | 2025.09.20 |
| 7. 파이썬 기초 - 5장 파이썬 날개 달기 [조코딩] (1) | 2025.09.20 |