문자열 치환 (replace, RexExp, match)
문자열 치환 (replace, RexExp, match)
일치하는 문자열을 강조하기
검색어와 일치하는 단어 강조표시 하기
String.prototype.replace() - 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 세 메서드를 알아보았다.
정규표현식은 상당히 활용도가 높으므로 틈틈이 공부해두면 많은 도움이 될 것 같다.