![[정규식 18] 실전 패턴 모음](https://img.thenullpage.com/posts/6602/6602_1_a53ec5.webp)
이번 편은 그동안 배운 조각들을 모아 실무에서 바로 쓰는 패턴을 만들어보는 시간이에요. 이메일, 링크, 날짜, 우편번호, 휴대폰 번호, 해시태그처럼 우리가 자주 마주치는 것들을 하나씩 잡아볼 거예요. 예제가 넉넉하니 직접 따라 치면서 감을 잡아 보세요. 다만 시작 전에 꼭 짚고 갈 게 하나 있어요.
여기 나오는 이메일, URL 패턴은 교육용 근사 패턴이에요. 무슨 말이냐면, 진짜 이메일이나 주소 규격은 훨씬 복잡해서 정규식만으로 완벽하게 검증하는 건 사실상 불가능해요. 별별 예외가 다 있거든요. 그래서 실무에서는 정규식으로 형태만 대충 걸러내고, 최종 확인은 인증 메일을 실제로 보내보거나 요청을 직접 날려보는 식으로 해요. 정규식으로 완벽 검증을 하려고 패턴을 점점 복잡하게 키우다 보면 오히려 읽기 힘들고 실수가 생기니, 형태 거르기까지만 맡긴다고 생각하면 마음이 편해요. 이 점만 기억하고 편하게 배워봐요.
18.1 이메일 모양을 뽑고 싶어요
본문에 섞인 이메일 주소를 찾아볼게요. 패턴은 [\w.+-]+@[\w-]+\.[\w.-]+예요. 길어 보여도 @를 기준으로 세 덩어리예요. 앞쪽 [\w.+-]+는 아이디 부분(글자, 숫자, 점, 더하기, 하이픈 허용), 가운데 @는 그대로 골뱅이, 뒤쪽 [\w-]+\.[\w.-]+는 도메인과 최상위 주소예요.
import re
re.findall(r'[\w.+-]+@[\w-]+\.[\w.-]+', '[email protected], [email protected]')
결과는 ['[email protected]', '[email protected]']이에요. 점이 들어간 아이디도, 더하기가 들어간 아이디도, sub.co.kr처럼 여러 단계로 이어진 도메인도 잘 잡혔죠? 여기서 +가 어떻게 쓰였는지 눈여겨보세요. [\w.+-]+의 대괄호 안에 있는 +는 후보 글자 중 하나(더하기 기호)고, 대괄호 바로 뒤에 붙은 게 아니라 클래스 안에 들어 있어요. 반면 클래스 밖에서 +는 한 개 이상 반복이라는 뜻이에요. 같은 기호라도 위치에 따라 뜻이 달라지는 거죠. 그래도 이건 근사일 뿐이라, 실제로 받는 메일함이 있는지는 이 패턴이 보장하지 못해요.
18.2 글에서 링크를 뽑고 싶어요
글 속의 http 링크를 찾아볼게요. 패턴은 https?://[\w./-]+예요. 핵심은 https?의 ?예요. ?는 앞 글자가 있어도 되고 없어도 된다는 뜻이라, s를 선택적으로 만들어 http와 https를 한 번에 잡아요. 뒤의 [\w./-]+는 주소에 흔히 쓰이는 글자, 숫자, 점, 슬래시, 하이픈을 이어서 먹어요.
re.findall(r'https?://[\w./-]+', 'see http://a.com and https://b.org/x')
결과는 ['http://a.com', 'https://b.org/x']이에요. http짜리와 https짜리가 모두 잡혔어요. 물음표 기호 뒤에 붙는 검색어(쿼리 문자열)나 포트 번호까지는 생략한 근사 버전이라, 특이한 주소는 놓칠 수 있다는 점도 알아 두세요.
18.3 표준 날짜를 찾고 싶어요
이제 값이 정해진 형식들이라 훨씬 마음이 편해요. 2024-01-15처럼 생긴 날짜를 찾아볼게요. 자릿수가 딱 정해져 있으니 개수를 지정하는 {n}으로 간단히 표현해요. 패턴은 \d{4}-\d{2}-\d{2}예요. 숫자 네 개, 하이픈, 숫자 두 개, 하이픈, 숫자 두 개라는 뜻이에요.
re.findall(r'\d{4}-\d{2}-\d{2}', '2024-01-15 and 2025-12-31')
결과는 ['2024-01-15', '2025-12-31']이에요. 형식이 딱 맞는 두 날짜가 잡혔죠? 한 가지 주의할 점은, 이 패턴은 형식만 볼 뿐 값은 안 따진다는 거예요. 그래서 2024-13-40처럼 세상에 없는 날짜도 형식만 맞으면 통과해요. 값이 실제로 말이 되는지는 별도로 확인해야 해요.
18.4 우편번호를 찾고 싶어요
한국 우편번호는 다섯 자리 숫자예요. 패턴은 \b\d{5}\b예요. 여기서 \b는 단어 경계(단어와 단어 아닌 부분 사이)를 뜻해요. 앞뒤를 \b로 감싸면 정확히 다섯 자리 숫자 덩어리만 잡혀요. 이걸 안 쓰면 여섯 자리, 일곱 자리 숫자에서 앞 다섯 개가 딸려 나올 수 있거든요.
re.findall(r'\b\d{5}\b', '우편 06236 서울')
결과는 ['06236']이에요. 딱 다섯 자리만 정확히 잡혔어요. 만약 \b 없이 \d{5}만 썼다면, 예컨대 123456789 같은 긴 숫자에서도 앞 다섯 개가 잘려 나와서 엉뚱한 값을 우편번호로 오해할 수 있어요. 그래서 자릿수가 고정된 값을 찾을 때 \b로 앞뒤를 막아주는 습관은 정말 유용하니 익혀 두세요.
18.5 휴대폰 번호를 찾고 싶어요
이건 조금 까다로워요. 사람들이 010-1234-5678처럼 하이픈을 넣기도 하고 01012345678처럼 안 넣기도 하니까요. 둘 다 잡으려면 하이픈을 선택적으로 만들어야 해요. 패턴은 01[016789]-?\d{3,4}-?\d{4}예요. 01[016789]는 통신 국번(010, 011 등), -?는 하이픈이 있어도 없어도 됨, \d{3,4}는 중간 자리가 세 자리나 네 자리로 유동적임을 표현해요.
re.findall(r'01[016789]-?\d{3,4}-?\d{4}', '010-1234-5678 0111234567')
결과는 ['010-1234-5678', '0111234567']이에요. 하이픈이 있는 번호도, 없는 번호도 모두 잡혔죠? -?로 선택적 기호를 표현하고 \d{3,4}로 유동적인 자릿수를 다루는 이 조합은 다른 형식에도 두루 응용할 수 있어요.
18.6 해시태그를 뽑고 싶어요
마지막으로 SNS 글에서 자주 보는 해시태그예요. 패턴은 #\w+로 아주 간단해요. # 뒤에 단어 글자(\w는 영문, 숫자, 밑줄)가 한 개 이상 이어지는 걸 잡아요.
re.findall(r'#\w+', '봐요 #regex 그리고 #python3')
결과는 ['#regex', '#python3']이에요. 숫자가 섞인 태그도 잘 잡혔죠? SNS 텍스트에서 태그를 모아 통계를 내거나 분류할 때 기본이 되는 패턴이에요.
18.7 정리
오늘은 실전 패턴 여섯 개를 만들어봤어요. 이메일 [\w.+-]+@[\w-]+\.[\w.-]+, 링크 https?://[\w./-]+, 날짜 \d{4}-\d{2}-\d{2}, 우편번호 \b\d{5}\b, 휴대폰 01[016789]-?\d{3,4}-?\d{4}, 해시태그 #\w+예요. 자릿수가 고정된 값은 {n}으로 딱 맞게, 유동적인 부분은 ?와 {n,m}으로 표현한다는 감을 잡으셨을 거예요. 다시 강조하지만 이메일과 URL은 형태만 걸러내는 근사 패턴이라, 진짜 유효한지는 실제 발송이나 요청으로 확인해야 한다는 점 잊지 마세요. 이 패턴들을 자기 데이터에 넣어보면서 조금씩 다듬으면 여러분만의 실전 도구가 될 거예요.