[EXT-028][실무] 여러 언어의 글자 범주를 정규식으로 검사하기 > IT 기술 공유

본문 바로가기
사이트 내 전체검색

IT 기술 공유

[EXT-028][실무] 여러 언어의 글자 범주를 정규식으로 검사하기

페이지 정보

profile_image
작성자 기술팀장
댓글 0건 조회 6회 작성일 26-09-08 18:36

본문

[이번 수업]

`가-힣`이나 `A-Z`처럼 문자 범위를 직접 나열하지 않고 JavaScript 정규 표현식의 Unicode 속성 이스케이프를 사용합니다. 한글·라틴 문자·한자를 함께 받는 이름 검증을 만들고, 허용 문자와 보안 정책은 별개라는 점을 익힙니다.

[선수지식]

EXT-003의 정규식 기초와 EXT-009의 Unicode 정규화를 알면 좋습니다. 문자 속성(property)은 글자마다 문자, 숫자, 결합 부호, 사용 문자 체계 같은 특징을 붙인 표준 정보입니다.

[학습목표]

1. `\p{...}`와 `\P{...}`의 뜻을 설명할 수 있습니다.
2. Unicode 속성으로 여러 언어의 이름 형식을 검사할 수 있습니다.
3. 정규식 통과와 서비스의 보안 허용을 구분할 수 있습니다.

[핵심개념]

Unicode 모드 정규식에서 `\p{Property}`는 지정한 속성을 가진 문자에, `\P{Property}`는 그 반대 집합에 대응합니다. JavaScript에서는 패턴 뒤에 `u` 또는 `v` 플래그가 있어야 Unicode 속성 이스케이프로 동작합니다. `Letter`, `Mark`, `Number`는 Unicode 일반 범주(General_Category)의 값입니다. Letter는 여러 문자 체계의 글자, Mark는 앞 문자와 결합하는 부호, Number는 숫자로 분류된 문자를 뜻합니다.

`\p{Letter}`는 영어 알파벳만 뜻하지 않습니다. `\p{Number}`도 ASCII의 0~9보다 넓으므로 로그인 코드처럼 서양 숫자만 허용할 곳에는 `[0-9]`가 더 명확합니다. 특정 문자 체계를 확인할 때는 `Script`보다 여러 문자 체계에서 함께 쓰이는 문자를 반영하는 `Script_Extensions`가 더 알맞을 수 있습니다. 실제 허용 범주는 제품 요구사항으로 먼저 정해야 합니다.

아래 패턴은 첫 문자를 Letter로 제한하고, 이후 1~19개 코드 포인트에 Letter·Mark·Number·밑줄·하이픈을 허용합니다. 이는 2~20개의 화면 글자를 정확히 보장하는 규칙이 아닙니다. 사용자 눈에 보이는 글자 수는 Intl.Segmenter로 따로 검사해야 합니다.

[따라하기]

unicode-name.js 파일에 아래 코드를 저장합니다.

```javascript
const namePattern = /^\p{Letter}[\p{Letter}\p{Mark}\p{Number}_-]{1,19}$/u;
const names = ['홍길동', 'Jose\u03012', '東京_7', '7start', 'name space'];

for (const rawName of names) {
  const name = rawName.normalize('NFC');
  console.log(`${name}: ${namePattern.test(name)}`);
}
```

`node unicode-name.js`를 실행합니다. 확인한 예상 결과는 `홍길동`, `José2`, `東京_7`이 true이고 `7start`, `name space`가 false입니다. 결합 악센트가 든 두 번째 입력은 NFC 정규화 뒤 하나의 é로 표시됩니다. Windows PowerShell·명령 프롬프트, macOS 터미널, Linux 셸에서 명령은 같습니다. 런타임의 Unicode 데이터 버전에 따라 새로 추가된 문자의 분류는 달라질 수 있습니다.

[흔한 실수]

`u` 플래그를 빼면 `\p`가 기대한 속성 검사로 동작하지 않습니다. Letter를 모든 사용자 이름에 안전한 문자라고 해석하거나 Number를 0~9로 오해하지 마세요. 정규화하지 않은 결합 문자는 길이와 비교 결과가 달라질 수 있습니다. 정규식만 통과하면 이름 중복, 금칙어, 혼동 문자까지 해결된다고 생각해서도 안 됩니다. `^`와 `$`를 빼면 문자열 일부만 조건에 맞아도 성공할 수 있습니다. 여러 번 test()할 고정 검증 패턴에는 상태가 바뀌는 `g` 플래그를 붙이지 않는 편이 안전합니다.

[보안 주의]

허용할 문자 체계, 구두점, 최소·최대 길이를 업무 정책으로 명시합니다. 입력은 UTF-8 바이트 수와 그래핌 수를 먼저 제한하고 NFC 등 정한 형식으로 정규화한 뒤 검사합니다. 서로 닮은 다른 문자와 보이지 않는 문자는 Unicode 속성만으로 막을 수 없으므로 중요한 식별자에는 추가 점검과 사용자 확인이 필요합니다. 사용자가 보낸 문자열로 정규식 소스를 직접 만들지 말고 고정된 패턴을 사용합니다. 출력은 HTML이 아닌 일반 텍스트로 처리하며 실습은 본인 소유의 로컬 데이터에서만 진행합니다.

[직접 해볼 과제]

예제에 아랍 문자 이름, 밑줄로 시작하는 이름, 한 글자 이름을 추가해 결과를 기록하세요. 이어서 요구사항을 ‘한글 Script_Extensions와 ASCII 숫자만, 2~12 그래핌’으로 정하고 속성 검사와 Intl.Segmenter 길이 검사를 나눈 validateName 함수를 작성하세요.

[확인문제]

1. 정규식에서 Unicode 속성 이스케이프를 쓸 때 `u` 또는 `v` 플래그가 필요한 이유는 무엇인가요?
2. `\p{Number}`와 `[0-9]`는 어떻게 다른가요?
3. `\p{Letter}` 검사를 통과해도 중요한 식별자에 추가 검증이 필요한 이유는 무엇인가요?

[다음 학습]

다음에는 RegExp.escape()로 검색어를 정규식에 안전하게 넣고, 사용자 문자열을 정규식 문법으로 오해하지 않게 만드는 방법을 배웁니다.

[공식 참고 자료]

ECMAScript 2025 문자 클래스 이스케이프: https://tc39.es/ecma262/2025/multipage/text-processing.html#sec-characterclassescape
Unicode UTS #18 정규 표현식: https://www.unicode.org/reports/tr18/tr18-25.html
Unicode UAX #44 문자 데이터베이스: https://www.unicode.org/reports/tr44/

댓글목록

등록된 댓글이 없습니다.

회원로그인

회원가입

사이트 정보

회사명 : 회사명 / 대표 : 대표자명
주소 : OO도 OO시 OO구 OO동 123-45
사업자 등록번호 : 123-45-67890
전화 : 02-123-4567 팩스 : 02-123-4568
통신판매업신고번호 : 제 OO구 - 123호
개인정보관리책임자 : 정보책임자명

접속자집계

오늘
3,899
어제
6,862
최대
16,772
전체
769,850
Copyright © 소유하신 도메인. All rights reserved.