원본: Replace All String Occurrences in JavaScript
자바스크립트에서는 특정 문자열을 모두 다른 문자열로 바꾸는 간단한 방법이 없습니다.
이 포스트에서는 문자열 치환을 위해 문자열을 분할한 후 결합하는 방법과 String.replace() 메소드에 정규식을 사용하는 방법으로 모든 문자를 치환하는 방법을 알아보겠습니다.
또한 한번에 문자열의 모든 문자를 바꿀 수 있는 새로운 replaceAll() 메소드도 알아보겠습니다. replaceAll() 메소드는 사용하기 가장 편리한 방법이지만 es6를 지원하는 브라우저에서만 실행됩니다.
Table of Contents
split(), join() 메소드 사용
구글에 “자바스크립트에서 모든 문자열 항목 바꾸기”를 검색하면 가장 먼저 찾을 수 있는 접근방법은 배열을 사용하는 것 입니다.
방법은 다음과 같습니다:
const pieces = string.split(search);
const resultingString = pieces.join(replace);
먼저 split() 메소드를 사용하여 문자열 string을 검색할 문자열 search로 분할합니다.
그 다음 배열 pieces에서 join 메소드를 사용하여 바꿀 문자열 replace로 결합합니다.
예를 들어 ‘shinyks go go’라는 문자열에서 모든 공백 ‘ ‘을 하이픈 ‘-‘으로 치환하려면 다음과 같이 하면됩니다.
const search = ' ';
const replaceWith = '-';
const result = 'shinyks go go'.split(search).join(replaceWith);
console.log(result);
개발자 도구에서 실행하면 ‘shinyks go go’.split(‘ ‘) 구문은 문자열을 [‘shinyks’, ‘go’, ‘go’]와 같은 형태의 배열로 분할합니다.
그 다음 [‘shinyks’, ‘go’, ‘go’].join(‘-‘) 구문을 통해 각각의 항목 사이에 ‘-‘을 넣어 배열의 항목을 이어붙이고, 그 결과를 console.log() 메소드로 출력하면 ‘shinyks-go-go’를 얻을 수 있습니다.
다음은 분할 및 결합 방식을 일반화한 헬퍼 함수 입니다.
function replaceAll(string, search, replace) {
return string.split(search).join(replace);
}
replaceAll('abba', 'a', 'i');
replaceAll('go go go!', 'go', 'move');
replaceAll('oops', 'z', 'y');
지금 까지 설명한 방법은 문자열을 배열로 변환하고 그 다음 다시 문자열로 바꿨습니다. 이제 이보다 더 나은 방법이 있는지 알아보겠습니다.
replace 메소드와 정규식
String.replace(regExpSearch, replaceWith)는 정규식 regExpSearch로 검색하여 replaceWith로 바꿉니다.
replace() 메소드를 사용하여 패턴의 모든 항목을 바꾸려면 정규식에서 전역 플래그를 활성화 해야 합니다:
- 정규식 리터럴의 끝에 g 추가: /search/g
- 또는 정규식 생성자를 사용할 경우 두번 째 인수에 g 추가: new RegExp(‘search’, ‘g’)
이제 메소드를 사용해 공백 ‘ ‘을 ‘-‘로 바꿔보겠습니다.
const searchRegExp = /\s/g;
const replaceWith = '-';
const result = 'shinyks go go'.replace(searchRegExp, replaceWith);
console.log(result);
정규식 리터럴 /\s/g (글로벌 플래그 g 확인)은 ‘ ‘을 포함한 공백을 확인합니다.
‘shinyks go go’.replace(/\s/g, ‘-‘) 구문은 /\s/g로 매치되는 모든 문자열을 ‘-‘로 바꿔서 ‘shinyks-go-go’라는 결과를 만듭니다.
여기서 정규식에 i 플래그를 추가해 대소문자를 구분하지 않는 정규식을 만들 수 있습니다:
const searchRegExp = /go/gi;
const replaceWith = 'move';
const result = 'Shinyks Go go'.replace(searchRegExp, replaceWith);
console.log(result);
정규식 /go/gi (플래그 i 확인)는 문자열에서 대소문자를 구분하지 않는 검색을 하게하여 ‘Go’와 ‘go’가 모두 매치됩니다.
‘Shinyks Go go’.replace(/go/gi, ‘move’) 구문에서는 /go/gi에 매치되는 모든 문자열을 ‘move’로 변경합니다.
replace 메소드 주의 사항
정규식에는 정규식 내에서 사용하는 특별한 의미가 있는 문자가 있기 때문에 – [ ] / { } ( ) * + . . \ ^ $ | 와 같은 문자를 사용하려면 이스케이프해야 합니다.
따라서 특수문자를 그냥 정규식으로 찾을 때에는 문제가 됩니다. 다음 예를 보겠습니다.
const search = '+';
const searchRegExp = new RegExp(search, 'g');
위의 예제에서는 검색 문자열 ‘+’를 정규식으로 변환하려 합니다. 그러나 ‘+’는 잘못된 정규식이기 때문에 위와 같이 구문 오류가 발생합니다.
여기서는 ‘+’를 ‘\\+’로 이스케이프 하여 문제를 해결할 수 있습니다.
const search = '\\+';
const searchRegExp = new RegExp(search, 'g');
const replaceWith = '-';
const result = '5+2+1'.replace(searchRegExp, replaceWith);
console.log(result);
위의 예제와는 다르게 정규식을 사용하지 않고 String.replace(search, replaceWith) 구문의 search에 문자열을 넣을 경우 첫 번째 매치만 변경이 됩니다.
const search = ' ';
const replace = '-';
const result = 'shinyks go go'.replace(search, replace);
console.log(result);
‘shinyks go go’.replace(‘ ‘, ‘-‘) 구문은 처음에 만난 공백만을 치환합니다.
replaceAll 메소드 사용
마지막으로 String.replaceAll(search, replaceWith) 구문은 모든 search에 매치되는 문자열을 replaceWith로 바꿔줍니다.
다음 예제에서 공백 ‘ ‘을 ‘-‘로 바꾸는 방법을 확인하겠습니다:
const search = ' ';
const replaceWith = '-';
const result = 'shinyks go go'.replaceAll(search, replaceWith);
console.log(result);
‘shinyks go go’.replaceAll(‘ ‘, ‘-‘) 구문은 모든 공백 ‘ ‘을 ‘-‘로 바꿨습니다.
String.replaceAll(search, replaceWith)이 문자열의 모든 항목을 바꾸는 가장 좋은 방법입니다. 하지만 es6를 지원하지 않는 브라우저에서는 사용할 수 없습니다.
정리
문자열의 항목을 치환하는 기초적인 접근 방법은 특정 문자열을 기준으로 배열로 분할하고 그 분할된 배열을 새로운 문자열과 함께 합치는 것 입니다. String.split(search).join(replaceWith)과 같은 구문을 사용하면 잘 작동합니다. 하지만 이는 진부한 방법입니다.
또 다른 방법은 String.replace(searchRegExp, replaceWith) 구문을 사용해 정규식과 전역 플래그를 사용하는 것 입니다.
안타깝게도 정규식에서는 특수문자를 이스케이프 해야하므로 런타임에서 문자열로 정규식을 간단하게 생성할 수 없습니다. 그리고 간단한 문자열 교체를 위해 정규식을 사용한다는 것은 오버입니다.
마지막으로 String 객체의 새로운 메소드 replaceAll()이 문자열의 모든 항목을 바꾸는데 가장 적합합니다. es6 관련이나 polyfill 등 주의 깊게 사용한다면 replaceAll() 메소드를 사용하는 것이 가장 좋은 방법일 것 입니다.