hangul-toolkit
v0.1.0
Published
한국어 텍스트 처리 유틸리티 — 조사 선택, 자소 분해/조합, 숫자→한글 변환, 개인정보(PII) 마스킹 / Korean text utilities: josa picker, syllable disassemble/assemble, number-to-Korean, PII masking for LLM preprocessing
Maintainers
Readme
hangul-toolkit
한국어 텍스트 처리에 필요한 것들을 한 곳에 모은 유틸리티 라이브러리. A toolkit of Korean (Hangul) text utilities for JavaScript/TypeScript.
왜 hangul-toolkit인가 / Why
한국어 서비스를 만들다 본면 매번 필요한데, 매번 직접 구현하게 되는 것들:
- 조사 선택 — "사과를" vs "사과을"? 받침 유무에 따라 은/는, 이/가, 을/를을 자동 선택
- 자소 분해·조합 — 검색어 자동완성, 초성 검색의 기반
- 숫자 → 한글 — 금액 표기, 문서 생성
- 개인정보 마스킹 — LLM API에 프롬프트를 별내기 전 주민등록번호·전화번호·카드번호·이메일 자동 마스킹
- 번호 유효성 검증 — 주민등록번호, 사업자등록번호 체크섬 검증
Common Korean-text problems that developers keep re-implementing: particle (josa) selection, syllable disassembly for search/autocomplete, number-to-Korean conversion, PII masking before sending prompts to LLM APIs, and checksum validation for Korean identification numbers.
설치 / Installation
npm install hangul-toolkitNode.js 18+ / ESM·CommonJS·TypeScript 모두 지원합니다.
빠른 시작 / Quick Start
import { josa, disassemble, assemble, numberToKorean, formatWon, maskPII, detectPII } from 'hangul-toolkit';
// 조사 자동 선택
josa('사과', '을/를'); // '사과를'
josa('책', '을/를'); // '책을'
josa('서울', '으로/로'); // '서울로' (ㄹ 받침 특수 규칙)
josa('부산', '으로/로'); // '부산으로'
josa('3', '이/가'); // '3이' (숫자는 발음 기준)
// 자소 분해 / 조합 (초성 검색의 기반)
disassemble('한글'); // 'ㅎㅏㄴㄱㅡㄹ'
assemble('ㄱㅏㅂㅅ'); // '값'
assemble(disassemble('안녕하세요')); // '안녕하세요' (왕복 변환 보장)
// 숫자 → 한글
numberToKorean(123456789); // '일억이천삼백사십오만육천칠백팔십구'
formatWon(50000); // '오만원'
// 개인정보 마스킹 (LLM 프롬프트 전처리)
maskPII('홍길동 010-1234-5678 [email protected]');
// '홍길동 ***-****-**** ****@****.***'
maskPII('카드 1234-5678-9012-3456', { keepLast: 4 });
// '카드 ****-****-****-3456'
detectPII('연락처 010-1234-5678');
// [{ type: 'phone', value: '010-1234-5678', start: 4, end: 17 }]API 요약 / API
조사 / Particles
| 함수 | 설명 |
|---|---|
| josa(word, '은/는') | 단어에 올바른 조사를 붙여 반환 |
| pickJosa(word, '은/는') | 조사만 반환 |
| supportedJosaPairs() | 지원 조사 쌍 목록 (은/는, 이/가, 을/를, 과/와, 으로/로, 이나/나, 이랑/랑, 아/야, 이에요/예요 등 16종) |
음절 / Syllables
| 함수 | 설명 |
|---|---|
| decompose('한') | { choseong, jungseong, jongseong } |
| compose('ㅎ','ㅏ','ㄴ') | '한' |
| disassemble(text) | 문자열을 자모 나열로 |
| assemble(jamo) | 자모 나열을 문자열로 |
| hasBatchim(char) | 받침 여부 |
| isHangulSyllable(char) | 한글 음절 여부 |
숫자 / Numbers
| 함수 | 설명 |
|---|---|
| numberToKorean(n) | 123456789 → '일억이천삼백사십오만육천칠백팔십구' |
| formatWon(n) | 50000 → '오만원' |
개인정보 / PII
| 함수 | 설명 |
|---|---|
| detectPII(text, types?) | PII 탐지 (유형·위치 반환) |
| maskPII(text, { types?, maskChar?, keepLast? }) | PII 마스킹 (구분자 -, 공백 유지) |
| maskName('김철수') | '김*수' |
기본 탐지 유형: 주민등록번호(rrn), 전화번호(phone), 이메일(email), 신용카드(card), 운전면허번호(driverLicense). 계좌번호(account)는 오탐 가능성이 있어 기본 비활성이며 types 옵션으로 켤 수 있습니다.
검증 / Validation
| 함수 | 설명 |
|---|---|
| isValidRRN(input) | 주민등록번호 체크섬 검증 |
| isValidBusinessNumber(input) | 사업자등록번호 체크섬 검증 |
| isValidPhoneNumber(input) | 한국 전화번호 형식 검증 |
사용 사례: LLM 프롬프트 전처리 / Use case: LLM prompt preprocessing
import { maskPII } from 'hangul-toolkit';
const userPrompt = '내 번호가 010-1234-5678인데 요금제 문의할게';
const safe = maskPII(userPrompt, { keepLast: 4 });
// '내 번호가 ***-****-5678인데 요금제 문의할게'
await llm.chat(safe);기여 / Contributing
이슈와 PR을 환영합니다. 큰 변경은 먼저 이슈로 논의해 주세요.
npm install
npm test # vitest
npm run build # tsup (ESM + CJS + d.ts)아이디어: 한국 공휴일, 초성 검색 헬퍼, 한글→로마자 표기, 존칭/반말 변환 등 — 언제든 제안해 주세요.
