JavaScript / replace()로 문자열 바꾸기와 전체 치환 방법

String.replace(pattern, replacement)는 문자열에서 일치하는 부분을 바꾼 새 문자열을 반환합니다. 찾을 대상을 일반 문자열로 주면 첫 일치만 바꾸고 원본 문자열은 그대로 둡니다. 모두 바꾸려면 replaceAll()이나 g 플래그가 있는 정규표현식을 사용합니다.

replace()는 첫 일치만 바꿉니다

문자열을 찾는 경우 대소문자를 구분하며 맨 앞에서 발견한 첫 부분만 교체합니다. 대입한 결과를 사용하지 않으면 화면이나 원본 변수의 값은 바뀌지 않습니다. 바꾸려는 문자열이 없으면 결과는 원본과 같은 문자열입니다.

const original = '빨강 파랑 빨강';
const changed = original.replace('빨강', '초록');

console.log(changed);  // '초록 파랑 빨강'
console.log(original); // '빨강 파랑 빨강'
console.log(original.replace('검정', '초록')); // 원본과 같음

문자열은 변경 불가능한 값이며 replace()는 새 값을 만듭니다. 원본 대신 변경 결과를 계속 쓰려면 let text 변수에 다시 대입하거나 별도 변수로 저장하세요. 반환값의 조건은 MDN의 replace() 문서에서 확인할 수 있습니다.

모두 바꾸기와 대소문자 구분

고정된 문자열을 모두 바꾸려면 replaceAll()을 쓰면 됩니다. 정규표현식의 g 플래그도 전체 검색을 뜻합니다. i 플래그까지 붙이면 대소문자를 구분하지 않습니다. 정규표현식을 replaceAll()에 전달할 때는 g가 없으면 TypeError가 납니다.

const text = '빨강 파랑 빨강';
console.log(text.replaceAll('빨강', '초록')); // '초록 파랑 초록'

console.log('Red red'.replace(/red/gi, 'blue')); // 'blue blue' 

찾을 문자열에 정규표현식의 특수 문자가 포함되어도 replaceAll(".", "-")처럼 문자열 인수로 주면 점 문자 자체만 찾습니다. 정규표현식 /./g는 거의 모든 문자를 찾으므로 의미가 다릅니다. MDN의 replaceAll() 문서를 참고하세요.

바꿀 값에 $ 기호가 있을 때

바꿀 값을 문자열로 직접 전달하면 $&는 일치한 원래 문자열을 넣는 등 일부 $ 표기가 특별하게 해석됩니다. 사용자가 입력한 바꿀 값을 문자 그대로 넣어야 한다면 함수를 전달해 그 값을 반환할 수 있습니다. 함수가 반환한 문자열 안의 $&는 치환 기호로 다시 해석되지 않습니다.

console.log('빨강'.replace('빨강', '$&'));      // '빨강'
console.log('빨강'.replace('빨강', () => '$&')); // '$&' 

찾을 문자열이 빈 문자열이면 replace()는 맨 앞에 값을 삽입합니다. 이것이 의도한 동작이 아닌 입력 화면에서는 빈 검색어를 먼저 거르세요. 예제는 이 두 경우를 반영합니다.

전체 예제: 처음 한 번과 모두 바꾸기

아래 코드를 UTF-8로 replace-example.html에 저장하고 브라우저에서 엽니다. 원본·찾을 값·바꿀 값을 입력하고 모드를 고른 뒤 ‘바꾸기’를 누릅니다. 출력은 textContent로 표시하므로 입력 문구가 HTML 태그로 해석되지 않습니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>문자열 바꾸기 비교</title>
</head>
<body>
<label for="source">원본 문자열</label>
<input id="source" type="text" value="빨강 파랑 빨강">
<label for="search">찾을 문자열</label>
<input id="search" type="text" value="빨강">
<label for="replacement">바꿀 문자열</label>
<input id="replacement" type="text" value="초록">
<label for="mode">바꾸는 범위</label>
<select id="mode">
  <option value="first">처음 한 번: replace()</option>
  <option value="all">모두: replaceAll()</option>
</select>
<button id="change" type="button">바꾸기</button>
<button id="reset" type="button">처음으로</button>
<pre id="output" aria-live="polite"></pre>
<script>
const source = document.querySelector('#source');
const search = document.querySelector('#search');
const replacement = document.querySelector('#replacement');
const mode = document.querySelector('#mode');
const output = document.querySelector('#output');

function change() {
  const original = source.value;
  const find = search.value;
  const newText = replacement.value;
  if (find === '') {
    output.textContent = '찾을 문자열을 입력하세요.';
    return;
  }
  // 함수가 반환한 문자열은 $& 같은 치환 기호로 해석되지 않습니다.
  const result = mode.value === 'all'
    ? original.replaceAll(find, () => newText)
    : original.replace(find, () => newText);
  output.textContent = `원본: ${original}\n결과: ${result}`;
}

document.querySelector('#change').addEventListener('click', change);
document.querySelector('#reset').addEventListener('click', () => {
  source.value = '빨강 파랑 빨강';
  search.value = '빨강';
  replacement.value = '초록';
  mode.value = 'first';
  change();
});
change();
</script>
</body>
</html>

처음에는 결과: 초록 파랑 빨강이 보이고, ‘모두’를 고르면 결과: 초록 파랑 초록으로 바뀝니다. 바꿀 문자열을 $&로 넣어 보면 결과에 문자 그대로 들어갑니다. 찾을 값을 비우면 입력 안내가 나옵니다. ‘처음으로’를 누르면 기본 문장, 찾을 값, 바꿀 값과 첫 한 번 모드가 복원됩니다. 원본 줄을 함께 보여 주므로 새 문자열을 만들었다는 사실도 확인할 수 있습니다.