String.replace 자바스크립트 문자열 치환

원본: Replace All String Occurrences in JavaScript

자바스크립트에서는 특정 문자열을 모두 다른 문자열로 바꾸는 간단한 방법이 없습니다.

이 포스트에서는 문자열 치환을 위해 문자열을 분할한 후 결합하는 방법과 String.replace() 메소드에 정규식을 사용하는 방법으로 모든 문자를 치환하는 방법을 알아보겠습니다.

또한 한번에 문자열의 모든 문자를 바꿀 수 있는 새로운 replaceAll() 메소드도 알아보겠습니다. replaceAll() 메소드는 사용하기 가장 편리한 방법이지만 es6를 지원하는 브라우저에서만 실행됩니다.

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);
replace 메소드 사용 예제

개발자 도구에서 실행하면 ‘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');
replaceAll 헬퍼 함수

지금 까지 설명한 방법은 문자열을 배열로 변환하고 그 다음 다시 문자열로 바꿨습니다. 이제 이보다 더 나은 방법이 있는지 알아보겠습니다.

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);
replace 메소드 사용 예제

정규식 리터럴 /\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);
replace 메소드 예제

정규식 /go/gi (플래그 i 확인)는 문자열에서 대소문자를 구분하지 않는 검색을 하게하여 ‘Go’와 ‘go’가 모두 매치됩니다.

‘Shinyks Go go’.replace(/go/gi, ‘move’) 구문에서는 /go/gi에 매치되는 모든 문자열을 ‘move’로 변경합니다.

replace 메소드 주의 사항

정규식에는 정규식 내에서 사용하는 특별한 의미가 있는 문자가 있기 때문에 – [ ] / { } ( ) * + . . \ ^ $ | 와 같은 문자를 사용하려면 이스케이프해야 합니다.

따라서 특수문자를 그냥 정규식으로 찾을 때에는 문제가 됩니다. 다음 예를 보겠습니다.

const search = '+';
const searchRegExp = new RegExp(search, 'g');
RegExp 에러

위의 예제에서는 검색 문자열 ‘+’를 정규식으로 변환하려 합니다. 그러나 ‘+’는 잘못된 정규식이기 때문에 위와 같이 구문 오류가 발생합니다.

여기서는 ‘+’를 ‘\\+’로 이스케이프 하여 문제를 해결할 수 있습니다.

const search = '\\+';
const searchRegExp = new RegExp(search, 'g');
const replaceWith = '-';
const result = '5+2+1'.replace(searchRegExp, replaceWith);

console.log(result);
RegExp 이스케이프

위의 예제와는 다르게 정규식을 사용하지 않고 String.replace(search, replaceWith) 구문의 search에 문자열을 넣을 경우 첫 번째 매치만 변경이 됩니다.

const search = ' ';
const replace = '-';
const result = 'shinyks go go'.replace(search, replace);

console.log(result);
replace 메소드 사용 예제

‘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);
replaceAll 메소드 사용 방법

‘shinyks go go’.replaceAll(‘ ‘, ‘-‘) 구문은 모든 공백 ‘ ‘을 ‘-‘로 바꿨습니다. 

String.replaceAll(search, replaceWith)이 문자열의 모든 항목을 바꾸는 가장 좋은 방법입니다. 하지만 es6를 지원하지 않는 브라우저에서는 사용할 수 없습니다.

정리

문자열의 항목을 치환하는 기초적인 접근 방법은 특정 문자열을 기준으로 배열로 분할하고 그 분할된 배열을 새로운 문자열과 함께 합치는 것 입니다. String.split(search).join(replaceWith)과 같은 구문을 사용하면 잘 작동합니다. 하지만 이는 진부한 방법입니다.

또 다른 방법은 String.replace(searchRegExp, replaceWith) 구문을 사용해 정규식과 전역 플래그를 사용하는 것 입니다.

안타깝게도 정규식에서는 특수문자를 이스케이프 해야하므로 런타임에서 문자열로 정규식을 간단하게 생성할 수 없습니다. 그리고 간단한 문자열 교체를 위해 정규식을 사용한다는 것은 오버입니다.

마지막으로 String 객체의 새로운 메소드 replaceAll()이 문자열의 모든 항목을 바꾸는데 가장 적합합니다. es6 관련이나 polyfill 등 주의 깊게 사용한다면 replaceAll() 메소드를 사용하는 것이 가장 좋은 방법일 것 입니다.

관련 글