정규식 치환 $1 사용법과 $& 차이 정리

정규식 찾기·바꾸기에서 바꿀 문자열에 $1을 넣었는데 글자 그대로 "$1"이 찍히거나, 반대로 원하는 그룹 값이 아니라 다른 문자열이 나온다면 원인은 대부분 하나입니다. 정규식 모드가 꺼져 있거나, 찾을 문자열에 괄호로 그룹을 만들지 않은 것입니다.
이 글은 $1·$2 그룹 참조와 $&(전체 일치)가 실제로 어떤 문자열로 바뀌는지, 모드에 따라 결과가 왜 달라지는지를 예시로 짚습니다.
요약 ① 정규식 모드에서 $1, $2는 괄호로 묶은 그룹이 실제로 찾아낸 문자열로, $&는 매치된 전체 문자열로 바뀝니다. ② 정규식 모드를 끈 일반 모드에서는 찾을 문자열의 특수문자도, 바꿀 문자열의 $ 기호도 전부 글자 그대로 취급됩니다. ③ 화면의 "치환 횟수"는 만든 정규식(g/i 플래그 포함)이 원본 텍스트와 몇 번 일치했는지를 센 숫자입니다.
여러 줄 데이터를 순서만 바꿔야 할 때
주소록이나 명단을 정리하다 보면 "이름,전화번호" 순서로 된 줄을 "전화번호,이름" 순서로 통째로 바꿔야 하는 경우가 있습니다. 줄마다 이름과 번호가 전부 다르기 때문에, 문자 그대로 찾아 바꾸는 방식으로는 한 줄씩 손으로 고치는 수밖에 없습니다.
이럴 때 정규식으로 이름 부분과 전화번호 부분을 각각 괄호로 묶어 그룹으로 만들면, 바꿀 문자열에서 $1과 $2의 순서만 바꿔 모든 줄을 한 번에 처리할 수 있습니다. 날짜 형식을 바꾸거나 로그 앞뒤에 태그를 씌우는 작업도 같은 원리입니다.
도구 없이 확인하는 방법: 브라우저 콘솔에서 직접 실행하기
이 기능은 자바스크립트의 문자열 치환 함수(String.prototype.replace)를 그대로 감싼 것입니다. 그래서 브라우저 개발자 도구의 콘솔(F12 또는 Cmd+Option+I)에서 같은 결과를 직접 확인할 수 있습니다.
예를 들어 아래와 같은 두 줄짜리 텍스트가 있다고 하겠습니다.
홍길동,010-1234-5678
김철수,010-9876-5432
이름과 전화번호의 순서를 바꾸려면 콘솔에 다음과 같이 입력합니다.
"홍길동,010-1234-5678\n김철수,010-9876-5432".replace(/(.+),(.+)/g, "$2,$1")
// "010-1234-5678,홍길동\n010-9876-5432,김철수"
괄호로 묶은 첫 번째 그룹 (.+)이 $1, 두 번째 그룹이 $2가 됩니다. 정규식 끝의 g는 문자열 전체에서 일치하는 모든 부분을 바꾸라는 뜻이고, 이게 없으면 첫 번째 줄만 바뀌고 멈춥니다.
매치된 문자열 전체를 그대로 쓰고 싶으면 그룹 대신 $&를 씁니다. 전화번호 형식을 대괄호로 감싸는 경우입니다.
"010-1234-5678".replace(/\d{3}-\d{4}-\d{4}/, "[$&]")
// "[010-1234-5678]"
몇 번 바뀌었는지 세고 싶다면 같은 정규식으로 match()를 따로 실행해 배열 길이를 확인하면 됩니다. 위 두 줄짜리 텍스트라면 결과는 2입니다.
여기까지가 정규식 치환의 전체 원리입니다. 다만 콘솔을 열고 여러 줄 문자열을 직접 감싸고 정규식 리터럴을 매번 손으로 쓰는 과정은 번거롭습니다. 아래 도구는 같은 결과를 입력창에 텍스트를 붙여넣는 것만으로 실시간으로 보여줍니다.
저희 도구로 확인하기.
브라우저에서 바로 계산되며 입력한 텍스트는 서버로 전송되지 않습니다.

흔한 오해: 모드에 따라 결과가 달라지는 이유
정규식 치환에서 자주 걸리는 지점은 정리하면 다음과 같습니다.
| 상황 | 일반 모드 | 정규식 모드 |
|---|---|---|
찾을 문자열의 . * + ( ) 같은 기호 | 문자 그대로 찾습니다 | 정규식 메타문자로 해석됩니다 |
바꿀 문자열의 $1, $2 | 글자 그대로 "$1"이 출력됩니다 | 그룹이 찾은 문자열로 치환됩니다 |
바꿀 문자열의 $& | 글자 그대로 "$&"가 출력됩니다 | 매치된 전체 문자열로 치환됩니다 |
일반 모드에서 $ 기호가 그대로 남는 이유는 우연이 아닙니다. 일반 모드에서는 바꿀 문자열에 들어 있는 모든 $ 기호를 치환 직전에 $$로 먼저 바꿔둡니다. 그래서 $1이든 $&든 정규식 패턴으로 해석되지 않고 눈에 보이는 그대로 출력됩니다.
또 하나 자주 걸리는 지점은 괄호를 빠뜨리는 것입니다. 정규식 모드를 켰더라도 찾을 문자열에 괄호로 그룹을 만들지 않았다면 $1이 가리킬 그룹 자체가 없습니다. 이 경우 $1은 아무 값으로도 바뀌지 않고 글자 그대로 남습니다.
체크박스 하나도 결과를 바꿉니다. "대소문자 무시"를 켜면 대문자·소문자 구분 없이 찾고, 끄면 정확히 일치하는 경우만 찾습니다.
반면 텍스트 전체에서 일치하는 부분을 전부 찾는 동작은 체크박스와 무관하게 항상 켜져 있습니다. 그래서 같은 패턴이 여러 번 있으면 첫 번째 것만이 아니라 전부 바뀝니다.
정리
- 정규식 모드의 $1, $2는 괄호로 묶은 그룹이 실제로 찾아낸 문자열로 바뀝니다.
- $&는 그룹과 무관하게 정규식이 찾아낸 전체 문자열 그대로 바뀝니다.
- 일반 모드에서는 바꿀 문자열의 $ 기호가 전부 미리 이스케이프되어 글자 그대로 출력됩니다.
- 정규식에 괄호가 없으면 $1은 아무 값도 아니고 글자 그대로 남습니다.
- "치환 횟수"는 만든 정규식이 원본 텍스트와 몇 번 일치했는지를 센 숫자입니다.
브라우저에서 바로 계산되며 입력한 텍스트는 서버로 전송되지 않습니다.
자주 묻는 질문
그룹을 만들지 않고 $1을 쓰면 어떻게 되나요?
찾을 문자열에 괄호로 묶은 그룹이 없으면 $1이 가리킬 대상 자체가 없습니다. 이 경우 $1은 실제 값으로 치환되지 않고 글자 그대로 "$1"이라는 문자로 결과에 남습니다. $1을 쓰려면 찾을 문자열에서 해당 부분을 반드시 괄호로 감싸야 합니다.
일반 모드에서 바꿀 문자열에 $1을 넣으면 어떻게 되나요?
일반 모드(정규식 미사용)에서는 바꿀 문자열의 $ 기호가 치환 전에 전부 이스케이프됩니다. 그래서 $1이라고 입력하면 정규식 그룹 참조가 아니라 "$1"이라는 두 글자가 그대로 결과에 삽입됩니다. 그룹 참조를 쓰려면 정규식 모드를 켜야 합니다.
"치환 횟수"는 정확히 무엇을 세는 숫자인가요?
만든 정규식(대소문자 무시 옵션이 켜져 있으면 그것까지 반영)으로 원본 텍스트를 검사했을 때 일치한 개수입니다. 텍스트 전체에서 찾는 동작이 항상 켜져 있으므로, 같은 패턴이 여러 번 나오면 그 개수가 그대로 표시됩니다.
정규식을 잘못 입력하면 어떻게 되나요?
괄호를 닫지 않는 등 정규식 문법이 올바르지 않으면 도구가 오류 안내를 표시하고, 원본 텍스트는 바뀌지 않은 상태로 그대로 유지됩니다. 오류 문구를 보고 정규식을 고치면 해결됩니다.
