폼을 제출했는데 「형식 오류」가 뜨지만 눈으로 보기엔 완전히 올바른 것처럼 보인 적 있으신가요? 또는 Excel에서 정렬했을 때 같은 숫자가 엉뚱한 위치에 배치되는 경우를요? 이런 문제의 많은 원인이 바로 전각·반각 문자의 혼용입니다. 이 글에서는 두 가지의 정의부터 변환 시점까지 완전히 해설합니다.
1. 전각·반각의 정의
동아시아 문자셋(특히 CJK 환경)에서는 문자를 표시 너비에 따라 두 가지로 분류합니다.
| 종류 | 너비 | Unicode 범위(대표) | 예시 |
|---|---|---|---|
| 반각 | 1문자 너비 | U+0021–U+007E (ASCII 가시 문자) | A B C 1 2 ! @ # |
| 전각 | 2문자 너비 | U+FF01–U+FF60 (전각 ASCII 대응) | A B C 1 2 ! @ # |
전각 문자는 고정 너비 폰트에서 반각의 두 배 너비를 차지하며, 영숫자를 한자와 같은 너비로 정렬하기 위해 설계되었습니다. 반각 문자는 일반 ASCII 규격과 동일하며, 프로그램·URL·설정 파일에서 사용하는 표준 문자셋입니다.
한자·히라가나·가타카나는 원래 전각 범주에 속하므로 「반각 한자」는 존재하지 않습니다. 본 문서에서 다루는 전각/반각 변환은 주로 영문자, 숫자, 기호의 두 버전 전환을 의미합니다.
2. 전각과 반각의 구체적인 차이
| 종류 | 반각 | 전각 |
|---|---|---|
| 대문자 | A B C Z | A B C Z |
| 소문자 | a b c z | a b c z |
| 숫자 | 0 1 2 9 | 0 1 2 9 |
| 기호 | ! @ # $ % ( ) , | ! @ # $ % ( ) , |
| 공백 | (일반 스페이스 U+0020) | (전각 스페이스 U+3000) |
겉보기엔 같아 보이지만 Unicode 코드 포인트가 완전히 다릅니다. 컴퓨터가 비교·검색·정렬할 때 전혀 다른 문자로 처리합니다. 이것이 혼용 시 문제가 생기는 근본 원인입니다.
3. 왜 혼용이 발생하는가
전각 문자의 역사적 배경: 초기 CJK 문자셋은 영숫자 기호를 한자와 정렬해 표시하기 위해 전각 버전의 ASCII 문자를 수록했습니다. 일본어 IME 등의 입력기는 「전각 모드」를 제공하고 있어 혼용이 발생합니다.
- IME 전각 모드에서 입력한 숫자·기호(예: 한국어 입력 중 쉼표
,는 전각, 영문,는 반각). - Word·PDF·스캔 문서에서 복사·붙여넣기.
- 사용자가 전각/반각 모드를 인식하지 못하는 경우(스마트폰, 일본어 IME).
- 다른 시스템과의 데이터 연계 시 원본 데이터에 포함된 전각 문자.
4. 변환이 필요한 상황
4.1 폼 유효성 검사와 데이터베이스 저장
사용자가 전화번호를 02-1234-5678(전각 숫자)로 입력하면 정규 표현식 /^\d{2}-\d{4}-\d{4}$/이 일치하지 않습니다. 백엔드에서 데이터 수신 후 먼저 반각으로 정규화한 다음 유효성 검사를 실시해야 합니다.
4.2 검색과 매칭
데이터베이스에 반각 iPhone이 저장되어 있는데 사용자가 전각 iPhone으로 검색하면 결과가 0건이 됩니다. 애플리케이션 레이어에서 문자를 정규화한 후 검색해야 합니다.
4.3 CSV·Excel 데이터 처리
전각 숫자가 혼재하면 Excel의 SUM()이 해당 셀을 텍스트로 인식해 건너뛰거나, 정렬 시 전각 1이 9 뒤에 오는 문제가 발생합니다.
4.4 설정 파일·코드
JSON·YAML·.env 파일에 전각 따옴표 "나 전각 콜론 :이 혼입되면 파서가 오류를 냅니다. 육안으로는 발견하기 어렵습니다.
4.5 URL·이메일 주소
전각 문자는 URL이나 이메일 주소에 직접 사용할 수 없습니다. user@example.com의 전각 @(U+FF20)은 이메일 시스템이 인식하지 못합니다.
4.6 조판·인쇄
반대로, 전통적인 한·중·일 조판에서는 구두점·괄호 등에 전각이 필수인 경우가 있습니다. 이 경우는 반각→전각 변환이 필요합니다.
5. 변환 규칙과 주의 사항
전각 ASCII(U+FF01–U+FF5E)와 반각(U+0021–U+007E) 간의 변환은 단순한 오프셋 계산입니다:
// 전각 → 반각 (JavaScript)
function toHalfWidth(str) {
return str.replace(/[\uFF01-\uFF5E]/g, ch =>
String.fromCharCode(ch.charCodeAt(0) - 0xFEE0)
).replace(/\u3000/g, ' ');
}
// 반각 → 전각
function toFullWidth(str) {
return str.replace(/[\u0021-\u007E]/g, ch =>
String.fromCharCode(ch.charCodeAt(0) + 0xFEE0)
).replace(/ /g, '\u3000');
}
주의 사항: 전각 스페이스(U+3000)는 별도 처리 필요. 반각 가타카나(U+FF65–U+FF9F)는 별도 구간이므로 별도 로직 필요. 상대 시스템이 기대하는 형식을 확인한 후 변환 방향을 결정하세요.
6. 각 언어·플랫폼의 지원
| 언어 / 플랫폼 | 전각→반각 | 비고 |
|---|---|---|
| PHP | mb_convert_kana($str, 'a') | mbstring 확장 필요 |
| Python | unicodedata + str.translate | jaconv 패키지도 사용 가능 |
| JavaScript | 정규 표현식(위 참조) | 내장 함수 없음 |
| Excel | ASC() / JIS() | ASC() 전각→반각, JIS() 반각→전각 |
7. 실전 정규화 전략
- 백엔드에서 데이터 수신 후 즉시 정규화: 전화번호·우편번호 등 형식에 민감한 필드는 유효성 검사 전에 반각으로 변환.
- 검색 쿼리도 정규화: 검색 키워드와 검색 대상 데이터의 문자 기준을 통일해 히트율 향상.
- CSV 임포트 시 전처리: 데이터베이스에 입력하기 전에 전각 문자를 감지·변환하는 스크립트를 삽입.
- 설정 파일 Lint에 전각 문자 감지 추가: pre-commit hook이나 CI/CD로 오혼입을 조기 발견.
8. 정리
- 프로그램 로직·URL·API·데이터베이스 인덱스 컬럼 → 반각 우선.
- 전통적인 한·중·일 조판, 공문서, 인쇄물 → 규정에 따라 전각 기호 사용.
- 시스템 입구에서 한 번만 정규화하고 여러 곳에서 수정하지 않는다.
일괄 변환이 필요한 경우 텍스트 변환 도구를 이용하면 전각↔반각 변환을 빠르게 처리할 수 있습니다.