정규식 한글 패턴 매칭 완벽 가이드 - 자음 모음 음절까지 한번에 처리하는 법
한글 정규식이 자꾸 깨지는 이유가 궁금하셨다면 유니코드 범위부터 자음 모음 분리까지 실제 코드와 함께 정리했습니다. 검색 검증 치환 다 됩니다.
![]()
회원가입 폼에 "한글만 입력 가능"이라고 적어놓고 정규식을 짰는데, 막상 사용자가 "ㄱㄴㄷ"만 쳐도 통과되거나 반대로 정상 이름인데 거부되는 경험, 한 번쯤 겪어보셨을 겁니다. 한글은 영문과 달리 유니코드에서 여러 블록에 흩어져 있어서 단순히 [가-힣]만 쓰면 자음과 모음을 놓치고, [ㄱ-ㅎ]만 쓰면 완성형을 놓칩니다. 어디서부터 어디까지 잡아야 의도한 대로 동작하는지 정리해 두면 입력 검증, 치환, 텍스트 분석 어디에서나 바로 가져다 쓸 수 있습니다.
한글 유니코드 범위 이해하기
정규식 한글 패턴 매칭의 출발점은 유니코드 범위를 정확히 아는 것입니다. 한글은 유니코드에서 크게 세 영역으로 나뉩니다. 완성형 음절, 한글 자모, 호환 자모입니다. 각 블록의 코드 포인트가 다르기 때문에 한 영역만 잡으면 나머지가 모두 빠집니다.
| 영역 | 유니코드 범위 | 설명 |
|---|---|---|
| 한글 음절 | AC00 - D7A3 | 가 ~ 힣, 완성된 글자 11,172자 |
| 한글 자모 | 1100 - 11FF | 초성 중성 종성 분리 자모 |
| 호환 자모 | 3130 - 318F | ㄱ-ㅎ, ㅏ-ㅣ 입력기 자모 |
| 자모 확장A | A960 - A97F | 옛한글 확장 영역 |
| 반각 자모 | FFA0 - FFDC | 반각 한글 자모 |
실무에서는 보통 음절 영역과 호환 자모 두 군데만 다뤄도 충분합니다. 옛한글이나 반각 자모는 일반 입력기에서 거의 나오지 않기 때문입니다.
완성형 한글 매칭 패턴
가장 많이 쓰는 패턴은 완성형 음절만 잡는 [가-힣]입니다. JavaScript, Python, Java 모두 유니코드 리터럴로 동일하게 동작합니다.
- 완성형만: /^[가-힣]+$/
- 완성형 + 영문: /^[가-힣a-zA-Z]+$/
- 완성형 + 숫자 + 공백: /^[가-힣0-9\s]+$/
이름 입력 필드에서 가장 권장되는 패턴은 /^[가-힣]{2,10}$/ 같은 형태입니다. 두 글자 이상 열 글자 이하로 제한하면 "김" 한 글자, "ㄱ" 자음 단독, 비정상적으로 긴 입력을 한 번에 걸러낼 수 있습니다.
한글 정규식에서 가장 흔한 실수는 [가-힣]에 자음 모음이 포함된다고 착각하는 것입니다. "ㄱ", "ㅏ" 같은 단독 자모는 별도 영역이라 [가-힣]에는 절대 매칭되지 않습니다.
주의할 특수 음절
"갂", "갃", "갅" 같은 잘 쓰이지 않는 종성 음절도 가-힣 범위에 모두 포함됩니다. 데이터에 깨진 한글이 섞여 있을 때 이런 음절들이 검증을 통과해서 들어오는 경우가 있는데, 사실 정규식은 정상 동작한 것이고 입력 인코딩 자체를 의심해야 합니다.
자음 모음 분리 매칭하기
사용자가 검색창에 "ㅋ"만 쳤을 때 추천 목록을 띄우거나, 채팅 필터에서 "ㄱㄱ" "ㅇㅇ" 같은 자음 도배 패턴을 잡으려면 호환 자모 영역을 따로 다뤄야 합니다.
- 자음만: /^[ㄱ-ㅎ]+$/
- 모음만: /^[ㅏ-ㅣ]+$/
- 자음 + 모음: /^[ㄱ-ㅎㅏ-ㅣ]+$/
- 완성형 + 자모 전체: /^[가-힣ㄱ-ㅎㅏ-ㅣ]+$/
실전 활용 - 입력 검증과 치환
패턴을 알았으면 실제 코드에서 어떻게 쓰는지가 중요합니다. JavaScript와 Python으로 자주 쓰는 케이스를 정리했습니다.
한글만 추출하기
// JavaScript
const text = "Hello 안녕 123 世界";
const korean = text.match(/[가-힣]+/g);
// 결과: ["안녕"]
# Python
import re
text = "Hello 안녕 123 世界"
korean = re.findall(r'[가-힣]+', text)
# 결과: ['안녕']한글 제거 또는 비한글 제거
// 한글만 남기기
text.replace(/[^가-힣]/g, '');
// 한글 + 공백 + 영문 남기기
text.replace(/[^가-힣a-zA-Z\s]/g, '');회원가입 폼에서 닉네임을 검증하거나, 게시판에 도배성 자음 입력을 차단할 때 가장 많이 쓰입니다. 더미 텍스트로 테스트가 필요하다면 Lorem Ipsum 생성기에서 다양한 형식의 더미 문자열을 받아 정규식 동작을 검증해 보면 엣지 케이스를 빠르게 확인할 수 있습니다.
자주 발생하는 함정과 해결
한글 정규식을 쓰면서 만나는 흔한 문제 세 가지입니다.
1. 길이 계산이 이상하다
"안녕".length는 JavaScript에서 2가 나오지만, 옛한글이나 확장 한자처럼 BMP를 벗어난 글자는 length가 2로 잡힙니다. 한글 기본 음절은 BMP 안에 있어 1글자로 정확히 잡히지만, 이모지나 확장 영역까지 다뤄야 한다면 [...str].length를 쓰는 편이 안전합니다.
2. NFC vs NFD 정규화 문제
macOS에서 복사한 한글은 종종 NFD(자모 분리) 형태로 들어옵니다. "한글"이 ㅎ+ㅏ+ㄴ+... 형태로 분리되어 [가-힣] 패턴에 매칭되지 않습니다. 처리 직전에 str.normalize('NFC')로 정규화하면 깔끔하게 해결됩니다.
3. 정규식 플래그 누락
- g 플래그 없으면 첫 매치만 잡힙니다
- u 플래그 권장: 유니코드 안전 모드
- JavaScript에서 \p{Script=Hangul} 사용 시 u 플래그 필수
최신 환경이라면 /\p{Script=Hangul}/gu 같은 유니코드 속성 패턴을 쓰는 것도 좋습니다. 범위를 외우지 않아도 되고 확장 영역까지 자동으로 잡아줍니다.
한글 정규식은 한 번 정리해두면 평생 쓰는 자산입니다. 자주 쓰는 패턴은 코드베이스의 공통 유틸로 빼두시고, 새로운 입력 형식이 들어올 때마다 NFC 정규화 먼저 적용하는 습관을 들이시면 데이터 품질 문제의 절반은 자연스럽게 사라집니다.