17.14 역참조
그룹을 사용하면 역참조(backreference)라는 테크닉도 쓸 수 있습니다.
필자는 역참조를 자주 사용하는 편은 아니지만, 아주 유용하게 쓸 수 있는 경우가 하나 있습니다.
정말 유용한 예제를 보기 전에 먼저 인위적인 예제를 하나 봅시다.
XYYX 형태의 밴드 이름을 찾고 싶다고 합시다.
PJJP, GOOG, ANNA 등이 해당되겠죠.
역참조를 이런 경우에 유용하게 쓸 수 있습니다.
서브그룹을 포함해, 정규식의 각 그룹은 숫자를 할당받습니다.
숫자는 맨 왼쪽이 1번에서 시작해 오른쪽으로 갈 수록 1씩 늘어납니다.
역슬래시 뒤에 숫자를 써서 이 그룹을 참조할 수 있습니다.
즉 \n
은 맨 처음 일치한 그룹입니다.
예제를 봅시다.
const promo = "Opening for XAAX is the dynamic GOOG! At the box office now!";
const bands = promo.match(/([A-Z])([A-Z])\2\1/g);
이 정규식을 왼쪽에서 오른쪽으로 읽으면 그룹이 두 개 있고 그 다음에 \2\1
이 있습니다.
첫 번째 그룹이 X에 일치하고 두 번째 그룹이 A에 일치한다면 \2
는 A이고 \1
은 X입니다.
뭔가 대단한 것 같지만 별로 쓸모는 없을 거 같죠?
필자도 그렇게 생각합니다.
특이한 퍼즐을 풀 때를 제외하면, 필자가 실무에서 역참조를 사용하는 것은 따옴표의 짝을 맞출 때뿐입니다.
HTML에서는 태그의 속성값에 큰따옴표나 작은따옴표를 써야 합니다.
역참조를 이용하면 쉽게 찾을 수 있습니다.
// 작은 따옴표와 큰 따옴표를 모두 썼으므로 백틱으로 문자열 경계를 나타냈습니다.
const html = `<img alt='A "simple" example.'>` +
`<img alt="Don't abuse it!">`;
const matches = html.match(/<img alt=(['"]).*?\1/g);
이 예제는 좀 지나치게 단순화한 겁니다.
다른 속성이 alt 속성보다 앞에 있거나, alt 앞에 공백이 두 개 이상이라면 이 정규식으로는 아무 것도 찾지 못합니다.
나중에 이 예제를 다시 살펴보면서 그 문제를 해결할 겁니다.
밴드 이름 예제와 마찬가지로, 첫 번째 그룹은 따옴표 뒤에 0개 이상의 문자를 찾습니다(물음표를 썼으므로 소극적으로 일치해서, 두 번째 <img>
까지 진행하는 일은 없습니다).
그 다음에 있는 \1
는 앞에서 찾은 따옴표의 짝입니다.
적극적 일치와 소극적 일치에 대해 정확히 이해했는지 다시 한 번 확인해 봅시다.
바로 앞 예제의 정규식에서 *
다음의 물음표를 지우고 적극적으로 일치하게 만드십시오.
표현식을 다시 실행하십시오.
어떻게 되나요?
왜 그런지 이해할 수 있나요?
적극적 일치와 소극적 일치는 정규식을 정확히 사용할 수 있는지 판가름하는 매우 중요한 개념입니다.
아직 잘 모르겠다면 17.13절로 돌아가서 다시 읽어보시기 바랍니다.