최신 자바스크립트 문자열 바꾸기 메서드인 replaceAll() 사용하기

최근까지도 자바스크립트에는 다른 언어에서 지원되는 전역 문자열 바꾸기 기능이 없었습니다.

작년 그러니까 2021년이 되서야 ES2021(ES12) 표준 명세에 전역 문자열 바꾸기 메서드인 replaceAll() 이 추가되었습니다.

업데이트가 주기적으로 되는 대부분의 최신 웹 브라우저들은 이미 replaceAll() 메서드를 지원합니다.

개발자도구 콘솔에서 문자열에 replaceAll() 메서드를 적용해보면 지원하는지를 바로 확인할 수 있습니다.

replaceAll() 메서드가 지원되지 않는 웹 브라우저에서는 다음과 같이 "is not a function", 또는 "지원하지 않는 속성이나 메서드" 이라는 에러 메시지를 표시합니다.

replaceAll() 메서드가 없을 때도 replace() 와 정규표현식(Regular Expression)을 이용해서 유사한 기능을 구현해서 사용해왔기 때문에 전역 문자열 바꾸기 메서드가 없어도 크게 불편함은 없었습니다.

'바보 멍충이 바보'.replace(/바보/g, '멍충이');

정규표현식으로 replace를 replaceAll처럼 사용하는 방법은 다음 글을 참고하면 도움이 됩니다.

> 정규표현식으로 replace를 replaceAll 처럼 사용하기

replaceAll() 메서드는 최근에 추가된 만큼 전역 문자열 바꾸기와 연관이 있는 여러가지 강력한 기능들이 포함되었습니다.

replaceAll() 메서드는 단순 문자열 바꾸기 기능을 넘어 인자로 함수를 정의해서 문자열을 재 가공한 결과를 얻을 수도 있습니다.

인터넷 익스플로러에서는 지원되지 않습니다. 인터넷 익스플로러 호환성이 필요한 경우 replace 와 정규표현식을 사용해야 합니다.

전역(global) 문자열 바꾸기

기본 사용 방법은

'문자열'.replaceAll('찾을 문자열','바꿀 문자열')

입니다.

"문자열"에서 모든 "찾을 문자열"을 찾아서 "바꿀 문자열"로 대체합니다.

'아주 오래 전 바닷가 어느 왕국에 당신이 알지도 모를 어느 한 소녀가 살았지'.replaceAll('왕국', '인천')

정규표현식을 이용해 바꿀 문자열을 패턴으로 선택하기

replaceAll() 메서드는 찾을 문자열에 정규표현식을 사용할 수 있습니다.

정규표현식을 사용하면 복잡한 구조의 문자열 매칭을 할 수 있기 때문에 단순 문자열 변경만으로는 할 수 없는 다양한 문자열 변경 작업을 할 수 있습니다.

예를 들어 HTML 내용에서 하이퍼링크 경로를 모두 "#"으로 바꾸는 정규표현식 문자열 바꾸기를 다음처럼 사용할 수도 있습니다.

'<a href="./member">회원정보</a>'.replaceAll(/<a (.+ )?href="([^"]+)"([^>]+)?>/gi,'<a href="#">')

첫 번째 인자인 찾는 문자열의 정규표현식 패턴 "<a (.+ )?href="([^"]+)"([^>]+)?>"은 "<a href="하이퍼링크경로">" 패턴을 찾습니다.

"g" 옵션은 전역으로, "i" 옵션은 대소문자 무시입니다.

주의할 점이 하나 있습니다.

찾는 문자열에 정규표현식을 사용할 때는 글로벌 옵션(g)을 반드시 사용해야 합니다.

"g" 옵션을 사용하지 않으면 다음처럼 글로벌 옵션이 없이 정규표현식을 사용하면 안된다는 에러메시지가 표시됩니다.


바꿀 문자열을 찾는 문자열을 기준으로 정하기

바꿀 문자열 대신 "$"로 시작하는 지시자를 사용해서 찾는 문자열을 기준으로 바꿀 문자열을 정할 수 있도록 문자열 템플릿을 지원 합니다.

바꿀 문자열은 찾는 문자열을 기준으로, 또는 찾는 문자열의 앞뒤 문자열을 기준으로 자동으로 정해지기 때문에 찾는 문자열만 변경하면 되서 코드 관리가 단순해지는 장점이 있습니다.

다만 기능이 다소 제한적이어서 "$&"을 제외하고는 활용도가 다소 떨어집니다.

"$"와 조합해서 사용할 수 있는 지시자는 다음과 같습니다.

패턴 삽입하는 문자열
$& $&을 찾는 문자열로 대체합니다.
찾는문자열 앞뒤에 추가 내용을 덧붙여 바꾸기를 할 때 유용합니다.

str.replaceAll('찾는문자열', '??$&??');

'찾는문자열' -> '??찾는문자열??' 로 전체 문자열에서 바꾸기를 합니다.
$` 매치된 찾는 문자열 앞쪽에 나오는 하위 문자열을 바꿀 문자열로 사용합니다.
$' 매치된 찾는 문자열 뒤에 나오는 하위 문자열을 바꾸는문자열로 사용합니다.
$n n은 1~100사이의 정수입니다.

정규표현식으로 문자열 패턴을 매칭할 때 매치되는 하위 문자열이 여러 개일 때 하위 문자열을 순서대로 선택하는 지시자로 사용합니다. $2은 정규표현식으로 작성한 찾는 문자열에서 두 번째 매치된 하위 문자열이 됩니다.
하나의 찾는 하위 검색어는 괄호로 묶은 단위로 구분을 해야 $1, $2, $3 ... 로 구분을 하게 됩니다.

str.replaceAll(/(검색어1)(검색어2)/g, '$2$1')


매치되는 2개 이상의 검색 결과의 순서를 바꾸는 용도로 사용하면 유용합니다.

'라이언 어피치 콘 프로도 단무지 프로도'.replaceAll(/(프)(로도)/g,'$2$1')
-> '라이언 어피치 콘 로도프 단무지 로도프'

정규표현식의 단어 단위 패턴 조건(\w)은 한글 지원이 안됩니다.
문제를 일으킬 가능성이 있으므로 단어 단위 패턴은 사용하지 않는 것이 좋습니다.

인자 함수로 문자열 바꾸기 메서드를 커스터마이징 하기

replaceAll() 메서드는 두 번째 인자인 "바꿀 문자열" 인자에 문자열 대신 인자 함수를 정의해서 "찾은 문자열"을 여러 가지 방법으로 재 가공할 수 있는 방법을 제공합니다.

정규표현식과 인자 함수 두 가지를 활용하면 복잡한 도큐먼트 재처리 기능을 간단하게 구현할 수도 있습니다.

인자 함수는 정해진 파라메터 사용 규칙이 있습니다. 파라메터 개수는 찾는문자열의 하위 매칭 개수에 따라 달라집니다.

이름 파라메터로 넘어오는 값
match 찾은 문자열.
p1, p2 ... 찾는 문자열이 일반 문자열이면 p1 1개만 오게 됩니다. matrch와 p1이 같게 됩니다.
정규표현식으로 찾을 경우 찾는 조건에 매치 된 여러 개의 하위 문자열이 순서대로 담깁니다. 정규표현식으로 매칭하는 하위 문자열 패턴은 괄호로 묶어서 구분해야 p1, p2 ... 순서의 파라메터로 나누어 저장됩니다.
/(매칭조건1+)(매칭조건2+)/g 로 문자열을 찾으면, "매칭조건1"에 매칭된 하위 문자열은 p1에, "매칭조건2"에 매칭된 하위 문자열은 p2에 저장됩니다.
offset 전체 문자열 안에서 찾은 문자열의 시작 위치를 반환합니다.
string 전체 대상 문자열이 그대로 넘어옵니다.

매칭해서 찾은 문자열이 전체 문자열 안에서 여러 개가 나올 경우 여러 개의 결과가 모두 반환됩니다.

인자 함수 사용 방법은 다음과 같습니다.

str.replaceAll('찾는문자열', function(match, p1, p2, offset, string){return '바꿀 문자열'})

주의할 점이 있습니다.

전체 문자열에서 매칭해서 찾은 문자열이 나올 때마다 인자 함수가 한 번씩 실행됩니다.

그리고 인자 함수 안의 return 문으로 찾은 하위 문자열에 대한 처리 결과 값을 반환하지 않으면 undefined 가 반환되면서 찾는 문자열이 'undefined' 문자열로 대체됩니다. 

str.replaceAll('찾은문자열', 'undefined')

과 같게 됩니다.

인자 함수가 return 반환이 없으면 undefined를 반환합니다.

찾는 문자열이 정규 표현식이 아닌 일반 문자열이면 하위 문자열 파라메터는 발생하지 않습니다. p1, p2 ... 는 없으며, 두 번째 인자가 offset이 됩니다.

일반 문자열로 찾기를 하면 두 번째 인자가 찾는 문자열이 발견된 위치가 됩니다.

앞서의 $ 지시자를 사용하는 문자열 바꾸기를 인자 함수를 사용해 구현할 수 있습니다.

'라이언 어피치 콘 프로도 단무지 프로도'.replaceAll(/(프)(로도)/g,(str,sub1,sub2)=>{return sub2+sub1})

-> '라이언 어피치 콘 로도프 단무지 로도프'