본문 바로가기
IT/JavaScript

문자열 치환 (replace, RexExp, match)

by 무녈 2022. 3. 13.

문자열 치환 (replace, RexExp, match)

일치하는 문자열을 강조하기

검색어와 일치하는 단어 강조표시 하기

String.prototype.replace() - JavaScript | MDN

RegExp - JavaScript | MDN

replace 메서드와 RegExp 사용하기

  • RegExp
    • RegExp 생성자는 패턴을 사용해 텍스트를 판별할 때 사용
  • replace()
    • 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환
    • 패턴은 문자열 또는 정규식(RegExp)이 될 수 있다.

변수와 일치하는 단어 강조하기

RegExp 생성자와 replace의 조합으로 검색어와 일치하는 단어를 강조할 수 있다.

input element에 값을 입력하고 해당 단어가 포함된 단어들을 서버에 요청하여 불러온 뒤 렌더링을 시켜주어야 했다.

보기처럼 java라는 단어를 서버에 보내면 java가 포함된 단어들을 전달해준다.

해당 과제에서는 검색어가 들어가 있는 단어들 중에서, 검색어와 일치하는 단어들에 하이라이트 표시를 주어야 했다.

이 둘을 replace와 replace의 조합으로 원하는 결과를 얻을 수 있다.

1. replace 함수 사용하기

var newStr = str.replace(regexp|substr, newSubstr|function)

replace 함수의 사용방법이다.

첫 번째 매개변수에는 regexp|substr 에 내가 찾고자 하는 문자를, 두 번째 문자열은 바꾸고자 하는 문자열 또는 함수를 입력한다.

const $ul = document.createElement("ul");
for (let language of languageList) {
      const $li = document.createElement("li");
      $li.innerHTML = language;
      $ul.append($li);
		}

강조하는 표시가 없는 기존의 코드는 위와 같다.

input value가 포함된 단어를 전달받고 li element의 innerHTML에 단어를 할당한 뒤 ul 태그에 전달하였다.

이제 replace를 통해 입력한 단어와 일치하는 단어를 강조해보자.

const $ul = document.createElement("ul");
for (let language of languageList) {
      const find = $searchLanguage.value;
      language = language.replace(
        find,
        `<span class="Suggestion__item--matched">${find}</span>`
      );
      const $li = document.createElement("li");
      $li.innerHTML = language;
      $ul.append($li);
}
  • input value를 replace의 첫 번째 매개변수에 할당하고, 강조하는 속성을 가진 클래스명을 span 태그 안에 넣어 준 뒤, 해당 단어를 강조하도록 코드를 작성하였다.

  • 일치하는 단어가 있을 경우 정확히 하이라이트 표시를 한다.

하지만 대소문자가 다를 경우에는 어떨까?

java`라고 작성할 경우, 서버에서 불러온 검색에 Java` 와 대소문자가 다르기 때문에 강조하지 못하는 것을 확인할 수 있다. 이때 우리는 RexExp 생성자를 사용해야 한다.

2. RexExp 사용하기

/pattern/flags
new RegExp(pattern[, flags])
RegExp(pattern[, flags])

우선 대소문자와 상관없이 검색어와 일치하는 단어 모두에 하이라이트 표시를 하고 싶다.

이때 RexExp 생성자의 첫 번째 인자는 정규표현식 또는 표현식을, 두 번째 매개변수는 선택사항으로 정규 표현식에 추가할 플래그를 추가한다.

플래그의 종류는 아래와 같다.

  • g (global, 전역 판별) 처음 일치에서 중단하지 않고, 문자열 전체를 판별합니다.
  • i (ignore case, 대소문자 무시)
  • u 플래그까지 활성화된 경우, Unicode 대소문자 폴딩을 사용합니다.
  • m (multiline, 여러 줄)
  • 시작과 끝 문자(^과 $)가 여러 줄에 걸쳐 동작합니다. 즉, 전체 입력 문자열의 맨 처음과 맨 끝뿐만 아니라 (\\n이나 \\r로 구분되는) 각각의 줄의 처음과 끝도 일치합니다.
  • s ("dotAll"). 이 줄 바꿈에도 일치합니다.
  • u (unicode) pattern을 Unicode 코드 포인트 시퀀스로 처리합니다. (이진 문자열 (en-US) 참고)
  • y (sticky, 접착) 이 정규 표현식의 lastIndex 속성에 명시된 인덱스에서만 판별하고, 이전/이후 인덱스에서 판별을 시도하지 않습니다.

이중 나는 전달받은 단어 내 입력값이 어디에 존재하든 상관없이 필요하기 때문에 g와 대소문자를 무시하기 위해 i 속성이 필요하. 이 둘을 조합하여 아래와 같은 코드를 만들 수 있다.

const $ul = document.createElement("ul");
for (let language of languageList) {
      const find = $searchLanguage.value;
      const regexp = new RegExp(find, "gi");
      language = language.replace(
        regexp,
          `<span class="Suggestion__item--matched">${find}</span>`
      );
      const $li = document.createElement("li");
      $li.innerHTML = language;
      $ul.append($li);
    }

이전의 결과와 달리 모든 단어를 입력값과 일치하도록 변환하였다.

하지만 이때 우리가 입력한 단어와 일치하는 부분의 단어가 입력한 값과 같이 대소문자가 변경되었다.

이 부분을 수정해보자

3. 마지막으로 match 메서드 사용하기

String.prototype.match() - JavaScript | MDN

표현식과 일치하는 부분을 다른 변수에 저장한 뒤 그 값을 span 태그 사이에 다시 입력하면 되지 않을까 하고 찾아보게 되었다.

  • match
    • 문자열이 정규식과 매취 되는 부분을 검색
str.match(regexp)

match를 사용하여 최종적으로 코드를 아래와 같이 변경하였다.

const $ul = document.createElement("ul");
for (let language of languageList) {
	    const find = $searchLanguage.value;
      const regexp = new RegExp(find, "gi");
      const matchedWord = language.match(regexp);
      language = language.replace(
        regexp,
          `<span class="Suggestion__item--matched">${matchedWord}</span>`
        );
      const $li = document.createElement("li");
      $li.innerHTML = language;
      $ul.append($li);
    }

전달받은 단어의 대소문자 상관없이 입력값과 같은 단어를 위와 같은 방법으로 하이라이트 처리해주었다.

 

문자열을 강조하기 위해, replace, RexExp, match 세 메서드를 알아보았다.

정규표현식은 상당히 활용도가 높으므로 틈틈이 공부해두면 많은 도움이 될 것 같다.

반응형

'IT > JavaScript' 카테고리의 다른 글

DOMContentLoaded 이벤트 핸들링  (0) 2022.04.01
배열의 요소를 무작위로 섞기  (1) 2022.04.01
TypeScript vs PropTypes  (0) 2022.03.09
[JavaScript] null과 undefined  (0) 2022.01.19
렉시컬 스코프(Lexical Scope)  (0) 2021.09.17

댓글