JavaScript / includes()로 문자열 포함 여부 확인하기

String.includes(searchString)는 문자열 안에 특정 부분 문자열이 있는지 확인해 true 또는 false를 반환합니다. 대소문자를 구분하고, 두 번째 인수 position을 주면 그 위치부터 오른쪽에서 검색합니다. 검색어의 위치 자체가 필요하다면 indexOf()를 사용하세요.

부분 문자열이 있는지 확인하기

검색어가 문자열의 앞·중간·끝 어디에 있어도 포함되어 있으면 true입니다. includes()는 원본을 바꾸지 않으며 검색 위치가 아니라 불리언을 돌려줍니다. 목록에서 특정 단어가 들어간 항목을 표시하는 등 존재 여부만 필요한 조건문에 잘 맞습니다.

console.log('abzcd'.includes('z'));   // true
console.log('abzcd'.includes('bz'));  // true
console.log('abzcd'.includes('zcd')); // true
console.log('abzcd'.includes('x'));   // false

정규식은 검색 인수로 쓸 수 없으며 전달하면 TypeError가 발생합니다. 패턴 검색이 필요하다면 정규식의 별도 메서드를 선택하세요. MDN의 String.includes() 문서에 인수와 반환값이 정리되어 있습니다.

position에서 검색 시작하기

text.includes(term, position)의 두 번째 인수는 검색을 시작할 위치입니다. 원본의 앞 position개 UTF-16 단위를 지나 오른쪽에 검색어가 있는지 검사합니다. 생략하면 0부터 시작합니다. 위치가 음수이거나 길이보다 큰 경우의 처리까지 직접 제어해야 한다면 입력 범위를 먼저 검사하세요.

const text = 'abzcd';
console.log(text.includes('z', 2)); // true: 'zcd'에서 찾음
console.log(text.includes('z', 3)); // false: 'cd'에서 찾음
console.log(text.slice(3));        // 'cd'

여기서 위치 2는 세 번째 문자인 z를 포함하여 검사합니다. endsWith()의 두 번째 인수는 “어디에서 끝낼지”를 정하지만 includes()의 두 번째 인수는 “어디에서 시작할지”를 정하므로 혼동하지 마세요. String.endsWith()로 끝 문자열 검사하기와 비교할 수 있습니다.

대소문자와 빈 검색어 처리

영문 대소문자를 다르게 쓰면 일치하지 않습니다. 대소문자를 무시하는 단순한 영문 검색이라면 원본과 검색어를 같은 대소문자로 변환한 뒤 비교할 수 있습니다. 언어별 정교한 문자 비교가 필요한 검색은 별도 요구사항으로 검토해야 합니다.

console.log('Blue Whale'.includes('blue')); // false
console.log('Blue Whale'.toLowerCase().includes('blue')); // true
console.log('abc'.includes('')); // true

빈 문자열은 항상 포함된 것으로 처리됩니다. 검색창에서 아무 내용도 입력하지 않았을 때 결과 전체를 보여줄지, 검색어를 요구할지 정하고 그 정책을 includes() 호출 전에 구현하세요. undefined를 인수로 생략하면 글자 그대로 "undefined"를 찾으므로 검색어가 실제로 전달됐는지도 확인하는 편이 안전합니다.

전체 예제: 시작 위치를 바꿔 보기

아래 코드를 UTF-8로 string-includes.html에 저장해 브라우저에서 엽니다. 시작 위치 사용을 켜고 값을 바꾸면 어떤 부분에서 검색했는지와 결과가 함께 표시됩니다. 입력과 검사 결과는 페이지 안의 텍스트로만 다룹니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>문자열 포함 검색</title>
</head>
<body>
<label for="text">원본 문자열</label>
<input id="text" type="text" value="abzcd">
<label for="term">검색어</label>
<input id="term" type="text" value="z">
<label><input id="use-start" type="checkbox"> 시작 위치 사용</label>
<label for="start">시작 위치</label>
<input id="start" type="number" min="0" step="1" value="2" disabled>
<pre id="output" aria-live="polite"></pre>
<script>
const text = document.querySelector('#text');
const term = document.querySelector('#term');
const useStart = document.querySelector('#use-start');
const start = document.querySelector('#start');
const output = document.querySelector('#output');

function show() {
  const position = Number(start.value);
  if (useStart.checked && (start.value.trim() === '' ||
      !Number.isInteger(position) || position < 0)) {
    output.textContent = '검색 시작 위치에는 0 이상의 정수를 입력하세요.';
    return;
  }
  start.disabled = !useStart.checked;
  const value = text.value;
  const query = term.value;
  const part = useStart.checked ? value.slice(position) : value;
  const found = useStart.checked
    ? value.includes(query, position) : value.includes(query);
  output.textContent = `검색 대상 부분: ${JSON.stringify(part)}\n` +
    `검색어: ${JSON.stringify(query)}\n` +
    `includes() 결과: ${found}`;
}

text.addEventListener('input', show);
term.addEventListener('input', show);
useStart.addEventListener('change', show);
start.addEventListener('input', show);
show();
</script>
</body>
</html>

초기 문자열 abzcd에서 z는 포함되어 true입니다. 시작 위치 2를 사용하면 대상은 zcd라서 여전히 true, 3으로 바꾸면 cd라서 false입니다. 검색어를 비우면 true가 됩니다. 사용자용 검색 기능에서는 빈 검색어 정책을 따로 적용하세요.