본문 바로가기
dev/javascript

[javascript] 자바스크립트 특정 문자 모두 바꾸기 (replaceAll)

by 최연탄 2022. 10. 28.
728x90
반응형

참고: https://dmitripavlutin.com/replace-all-string-occurrences-javascript/

간단하게 JavaScript 문자열에서 특정 문자를 모두 바꾸는 방법은 없습니다. JavaScript 초기에 영감을 준 Java에서는 1995년 부터 replaceAll() 메소드를 지원했지만요!

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

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

1. split(), join() 메소드 사용

구글에 "JavaScript에서 모든 문자열 항목 바꾸기"를 검색하면 가장 먼저 찾을 수 있는 접근방법은 배열을 사용하는 것 입니다.

작동 방식은 다음과 같습니다:

1. 문자열 string을 검색할 문자열 search로 분할합니다.

const pieces = string.split(search);

2. 그 다음 배열을 바꿀 문자열 replace로 결합합니다.

const resultingString = pieces.join(replace);

예를 들면 'duck duck go'라는 문자열에서 모든 공백 ' '을 하이픈 '-'으로 치환하려면 다음과 같이 하면됩니다.

const search = ' ';
const replaceWith = '-';
const result = 'duck duck go'.split(search).join(replaceWith);

console.log(result);

'duck duck go'.split(' ') 구문은 문자열을 ['duck', 'duck', 'go']와 같은 형태의 배열로 분할합니다.

그 다음 ['duck', 'duck', 'go'].join('-') 구문을 통해 각각의 항목 사이에 '-'을 넣어 배열항목을 이어붙이고, 그 결과 'duck-duck-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');

이 방법은 문자열을 배열로 변환한 다음 다시 문자열로 바꿔야 합니다. 더 나은 방법이 있는지 다음을 보겠습니다.

2. replace() 메소드에 정규식 사용

문자열 메소드 string.replace(regExpSearch, replaceWith)는 정규식 regExpSearch로 검색하여 replaceWith로 바꿉니다.

replace() 메소드를 사용하여 패턴의 모든 항목을 바꾸려면 정규식에서 전역 플래그를 활성화 해야 합니다:

  1. 정규식 리터럴의 끝에 g 추가: /search/g
  2. 또는 정규식 생성자를 사용할 경우 두번 째 인수에 g 추가: new RegExp('search', 'g')

이제 replace() 메소드를 사용해 공백 ' '을 '-'로 바꿔보겠습니다.

const searchRegExp = /\s/g;
const replaceWith = '-';
const result = 'duck duck go'.replace(searchRegExp, replaceWith);

console.log(result);

정규식 리터럴 /\s/g (글로벌 플래그 g 확인)은 ' '을 포함한 공백을 확인합니다.

'duck duck go'.replace(/\s/g, '-') 구문은 /\s/g로 매치되는 모든 문자열을 '-'로 바꿔서 'duck-duck-go'라는 결과를 만듭니다.

여기서 정규식에 i 플래그를 추가해 대소문자를 구분하지 않는 정규식을 만들 수 있습니다:

const searchRegExp = /duck/gi;
const replaceWith = 'goose';
const result = 'DUCK Duck go'.replace(searchRegExp, replaceWith);

console.log(result);

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

'DUCK Duck go'.replace(/duck/gi, 'goose') 구문에서는 /duck/gi에 매치되는 모든 문자열을 'goose'로 변경합니다.

3. 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 = 'duck duck go'.replace(search, replace);

console.log(result);

'duck duck go'.replace(' ', '-') 구문은 처음에 만난 공백만을 치환합니다.

4. replaceAll() 메소드 사용

마지막으로 string.replaceAll(search, replaceWith) 구문은 모든 search에 매치되는 문자열을 replaceWith로 바꿔줍니다.

다음 예제에서 공백 ' '을 '-'로 바꾸는 방법을 확인하겠습니다:

const search = ' ';
const replaceWith = '-';
const result = 'duck duck go'.replaceAll(search, replaceWith);

console.log(result);

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

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

5. 정리

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

또 다른 방법으로는 string.split(search).join(replaceWith) 구문을 사용해 정규식과 전역 플래그를 사용하는 것 입니다.

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

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

반응형

댓글