- 분야: FE
- 기술 스택: React · TypeScript(TSX)
- 관련 기술: Unicode NFKC · 문자열 정규화 · 다중 토큰 AND 검색
문제와 원인
기존 검색은 입력 끝의 공백과 대소문자만 정리했다. 데이터 베이스는 대상 데이터베이스·SQL과 내부 공백이 달랐고, 전각 sql은 반각 sql과 달랐다. 별칭 정처기도 정식 과정명 정보처리에 포함되지 않아 검색에서 빠졌다.
수정 전 코드
matchesSearchQuery()
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
function matchesSearchQuery(query: string, ...values: string[]) {
const normalized = query.trim().toLocaleLowerCase("ko-KR");
return !normalized || values.some((value) => (
value.toLocaleLowerCase("ko-KR").includes(normalized)
));
}
수정 후 코드
SW 과정 선택에 공유 함수 matchesLearningSearch를 적용했다. 입력과 대상 모두 NFKC·소문자·별칭 치환을 거친다. 대상은 공백을 제거하고, 검색어는 토큰으로 나눠 모두 포함될 때 일치시킨다. 빈 검색어는 전체 항목을 통과시킨다.
matchesSearchQuery 연결
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
import { matchesLearningSearch as matchesSearchQuery } from "@shared/study/learning-search";
normalizedLearningSearchTokens() · matchesLearningSearch()
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
export function normalizedLearningSearchTokens(query: string) {
return query.normalize("NFKC").toLocaleLowerCase("ko-KR")
.replace(/정처기/gu, "정보처리")
.trim()
.split(/\s+/u)
.filter(Boolean);
}
export function matchesLearningSearch(query: string, ...values: unknown[]) {
const text = values
.map(value => String(value ?? ""))
.join(" ")
.normalize("NFKC")
.toLocaleLowerCase("ko-KR")
.replace(/정처기/gu, "정보처리")
.replace(/\s+/gu, "");
return normalizedLearningSearchTokens(query)
.every(token => text.includes(token));
}
검증 결과
로컬 함수 비교 6조건에서 같은 대상 문자열에 기존 함수·공유 함수를 적용했다. 누락됐던 4조건은 0/4 → 4/4, 전체 기대값 일치는 2/6 → 6/6으로 바뀌었다.
좌우로 이동해 전체 내용을 확인하세요. 키보드: ←·→, Home·End
| 입력 조건 | 기대 결과 | 수정 전 | 수정 후 |
|---|---|---|---|
| 띄어쓴 단어 | 일치 | 불일치 | 일치 |
| 과정명 내부 띄어쓰기 | 일치 | 불일치 | 일치 |
| 전각 영문 | 일치 | 불일치 | 일치 |
| 별칭 | 일치 | 불일치 | 일치 |
| 무관한 검색 | 불일치 | 불일치 | 불일치 |
| 빈 검색 | 일치 | 일치 | 일치 |
matchesLearningSearch("데이터 베이스", "데이터베이스·SQL")은 true, 같은 입력과 운영체제의 비교는 false다. sql은 NFKC 변환 뒤 sql로 검색된다.
같은 검색어·대상 문자열 여섯 쌍을 로컬 Node의 원본 전후 함수에 각 1회 다시 전달했다. 띄어쓰기·전각·별칭 네 입력이 모두 일치했고 무관한 문자열과 빈 검색어의 판정은 같았다.