[hook] useCreateFuzzyMatcher

JH Cho·2023년 3월 14일
0

React

목록 보기
27/27

https://taegon.kim/archives/9919
위 글 공부용

import { escapeRegExp } from 'lodash';

//초성검색
function ch2pattern(ch: string) {
  const offset = 44032; // 44032 : '가' 코드
  // 한국어 음절에 해당한다면?
  if (/[가-힣]/.test(ch)) {
    // ch에서 44032를 빼주고
    const chCode = ch.charCodeAt(0) - offset;

    // 28로 나눠서 떨어지면 중성까지만 있는거고 나머지가 남으면 종성까지 있는거.
    if (chCode % 28 > 0) {
      // 종성이 있는 경우는 ch를 그대로 반환
      return ch;
    }
    //종성이 없을 때는
    const begin = Math.floor(chCode / 28) * 28 + offset; // ex) 돈을 종성 빼버려서 '도'로.
    const end = begin + 27; //  end는 '돟'
    return `[\\u${begin.toString(16)}-\\u${end.toString(16)}]`; // 도~돟에 해당하는 유니코드
  }
  // 한글 자음만 있을 때는
  if (/[ㄱ-ㅎ]/.test(ch)) {
    const con2syl = {: '가'.charCodeAt(0),: '까'.charCodeAt(0),: '나'.charCodeAt(0),: '다'.charCodeAt(0),: '따'.charCodeAt(0),: '라'.charCodeAt(0),: '마'.charCodeAt(0),: '바'.charCodeAt(0),: '빠'.charCodeAt(0),: '사'.charCodeAt(0),
    };

    //as keyof typeof
    /*
    interface User {
     name: string;
     age: number;
     email: string;
     }

     keyof typeof User

     type UserKeys = "name" | "age" | "email";
    */
    // ㄱ~ㅅ 까지는 그대로 begin 주고
    // ㅅ 이후로는 해당 유니코드에서 'ㅅ'을 뺀다음 588을 곱하고 다시 ㅅ를 더해서 시작점 설정
    // end 는 중성과 종성을 곱해서 더해주기
    // ex)  ㅎ => begin : 하  end : 힣
    const begin =
      con2syl[ch as keyof typeof con2syl] ||
      (ch.charCodeAt(0) - 12613) * 588 + con2syl['ㅅ']; /* 'ㅅ'의 코드 */
    const end = begin + 587;
    return `[${ch}\\u${begin.toString(16)}-\\u${end.toString(16)}]`; // ex) 하-힣 에 대한 유니코드 범위
  }
  // 그 외엔 그대로 내보냄(영어 등등..)
  // escapeRegExp : 특수문자 있는 문자열을 정규표현식으로 바꿔주는 메서드(유니코드의 경우 특수문떄문에
  // 이스케이프 안하면 에러 뜰 수 있기 때문)
  return escapeRegExp(ch);
}

export default function createFuzzyMatcher(input: string) {
  const pattern = input.split('').map(ch2pattern).join('.*?');
  // 인풋을 하나씩 정규표현식화 시켜서 c a t  이런식으로 만듦.
  return new RegExp(pattern);
}
profile
주먹구구식은 버리고 Why & How를 고민하며 프로그래밍 하는 개발자가 되자!

0개의 댓글