문제 정의
두 개의 문자열을 인자로 받아, 첫 번째 문자열(main) 안에 두 번째 문자열(sub)이 총 몇 번 등장하는지 그 횟수를 반환하는 JavaScript 함수를 작성해야 합니다.
예를 들어 메인 문자열이 'This is the is main is string'이고 찾으려는 부분 문자열이 'is'라면, 'is'는 총 4번 나타나므로 결과값은 4가 되어야 합니다.
정규표현식(RegExp)을 이용한 해결 방법
가장 대표적인 방법은 전역(g) 플래그를 설정한 정규표현식 객체를 만들어 replace() 메서드와 함께 사용하는 것입니다. replace()는 일치하는 부분을 발견할 때마다 콜백 함수를 호출하므로, 콜백 안에서 카운터를 증가시키면 전체 등장 횟수를 구할 수 있습니다.
const main = 'This is the is main is string';
const sub = 'is';
const countAppearances = (main, sub) => {
const regex = new RegExp(sub, "g");
let count = 0;
main.replace(regex, () => {
count++;
});
return count;
};
console.log(countAppearances(main, sub)); // 4
실행 결과
위 코드를 실행하면 콘솔에 아래와 같은 값이 출력됩니다.
4
split()을 활용한 더 간단한 대안
정규표현식 없이도 한 줄로 같은 결과를 얻을 수 있습니다. 부분 문자열을 기준으로 문자열을 분할(split)하면 생성되는 조각의 개수에서 1을 뺀 값이 곧 등장 횟수입니다.
const countAppearances = (main, sub) => {
return main.split(sub).length - 1;
};
console.log(countAppearances('This is the is main is string', 'is')); // 4
참고로, 찾으려는 문자열에 마침표(.)나 별표(*) 같은 정규식 특수 문자가 포함될 가능성이 있다면 new RegExp() 방식은 의도치 않게 동작할 수 있습니다. 이런 경우에는 split()을 사용하는 편이 리터럴 문자열 기준으로 안전하게 매칭됩니다.
정리
문자열 등장 횟수를 세는 작업은 로그 분석, 검색어 하이라이트, 데이터 정제 등 실무에서 자주 필요한 기능입니다. 단순한 경우에는 split() 방식으로 충분하고, 대소문자를 무시하거나(i 플래그) 단어 경계(\b)를 지정하는 등 세밀한 제어가 필요하다면 정규표현식 방식을 선택하는 것이 좋습니다.