'hangul-util' 코드와 '한글 초성, 중성, 종성 구하기' 포스트를 기반으로 작성된 글입니다.
includeByCho('ㄱ', '귤')
// true
includeByCho('ㅅ과', '사과')
// true
코드 예시
코드
const CHO_HANGUL = [
'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];
const HANGUL_START_CHARCODE = "가".charCodeAt();
const CHO_PERIOD = Math.floor("까".charCodeAt() - "가".charCodeAt());
const JUNG_PERIOD = Math.floor("개".charCodeAt() - "가".charCodeAt());
function combine(cho, jung, jong) {
return String.fromCharCode(
HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong
);
}
function makeRegexByCho(search = "") {
const regex = CHO_HANGUL.reduce(
(acc, cho, index) =>
acc.replace(
new RegExp(cho, "g"),
`[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]`
),
search
);
return new RegExp(`(${regex})`, "g");
}
function includeByCho(search, targetWord) {
return makeRegexByCho(search).test(targetWord);
}
includeByCho('가ㅂ', '가방');
// true
includeByCho('ㅅ방', '가방');
// false
includeByCho('ㅂ', '가방');
// true
코드 풀이
// 초성배열
const CHO_HANGUL = [
'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
'ㄹ', 'ㅁ', 'ㅂ','ㅃ', 'ㅅ',
'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ',
];
// 한글 시작 유니코드
const HANGUL_START_CHARCODE = "가".charCodeAt();
// 초성, 종성 주기
const CHO_PERIOD = Math.floor("까".charCodeAt() - "가".charCodeAt());
const JUNG_PERIOD = Math.floor("개".charCodeAt() - "가".charCodeAt());
// 한글 결합 함수
function combine(cho, jung, jong) {
return String.fromCharCode(
HANGUL_START_CHARCODE + cho * CHO_PERIOD + jung * JUNG_PERIOD + jong
);
}
초성검색을 구현하기 위한 최소한의 정보와 함수를 선언해 줍니다.
// 초성검색
function makeRegexByCho(search = "") {
const regex = CHO_HANGUL.reduce(
(acc, cho, index) =>
acc.replace(
new RegExp(cho, "g"),
`[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]` // [시작-끝] -> [가-깋]
),
search
);
return new RegExp(`(${regex})`, "g");
}
makeRegexByCho('ㄱ');
// /[가-깋]/
초성검색을 위해서는 'ㅅㄱ'를 '/[사-싷][가-깋]/' 형태의 정규식을 생성해 주는 작업이 필요합니다.
각 초성의 시작 글자과 끝은 정해져 있으며, 예시로 초성 ‘ㄱ’ 은 (가~깋)까지의 모든 범위에 해당하며, /[가-깋]/ 정규식으로 탐색할 수 있습니다.
makeRegexByCho() 상세풀이
더보기
'ㄱ밥'.replace(/ㄱ/g, '[가-깋]');
// '[가-깋]밥'
'김ㅂ'.replace(/ㅂ/g, '[바-빟]');
// '김[바-빟]'
'ㅅ방ㅅ'.replace(/ㅅ/g, '[사-싷]');
// '[사-싷]방[사-싷]'
replace() 메서드를 이용하면, 특정 초성을 모두 /[글자 시작 - 글자 끝]/ 정규식으로 바꿀 수 있습니다.
const regex = CHO_HANGUL.reduce(
(acc, cho, index) =>
acc.replace(
new RegExp(cho, "g"),
`[${combine(index, 0, 0)}-${combine(index + 1, 0, -1)}]`
),
search
);
return new RegExp(`(${regex})`, "g");
reduce() 메서드를 이용해서 초기값을 검색어로 지정해 주고, 초성배열(CHO_HANGUL)을 순회하여 ㄱ~ㅎ까지의 모든 초성을 검색어에서 찾아 문자조합 범위 정규식( /[시작-끝]/ )으로 변환시켜 줍니다.
combine() 함수로 다음초성에서 - 1은 초성 끝 글자. (’다’ - 1 → ‘닣’)
// 초성검색 (검색어, 비교할 단어)
function includeByCho(search, targetWord) {
return makeRegexByCho(search).test(targetWord);
}
includeByCho('ㄱ', '귤');
// true
정규식을 이용해서 문자가 조건에 일치한 지 검증하는 과정만이 남았습니다. 이는 구현된 정규식에 regex.test() 메서드를 사용한다면, 초성검색 기능을 완성할 수 있습니다.
참고자료