끝나지 않는 프로그래밍 일기


1. 역참조(backreferences)


역참조(backreferences)란 무엇일까요? 말 그대로 역으로 참조하는 것을 나타냅니다. 정규 표현식에서는 패턴의 일부를 하위 표현식으로 묶으면, 첫번째로 나타나는 부분 문자열을 찾은 뒤에 역참조를 통해 이후에 나타나는 부분 문자열을 찾을 수 있습니다. 이때, 각 하위 표현식은 번호로 식별됩니다. 이 역참조를 통해서, 반복되는 두 문자를 쉽게 찾을 수 있습니다. 예를 들어서, why so so serious에서 역참조를 통해 so so를 일치시킬 수 있습니다. 더 확실한 이해를 위해 아래 예제부터 살펴보도록 합시다.


Reg. Expression:

\b([a-z]+) \1\b

Text:

why so so serious


위의 정규 표현식을 자세히 살펴보면, \b라는 메타 문자가 사용되었습니다. 이 \b는 단어의 경계를 구분짓는 메타 문자로, 여기 텍스트에선 공백이 단어와 단어를 구분짓는 문자이므로 공백은 \b와 같다고 생각하셔도 됩니다.


여기서 중요한건, [a-z]+를 하위 표현식으로 묶었다는 것입니다. 이렇게 묶은 하위 표현식은 임시 버퍼에 저장됩니다. 이 임시 버퍼에 접근하려면 \n을 통해 각 버퍼에 접근할 수 있습니다. 여기서 n은 최소 1부터 최대 99개의 하위 표현식을 저장할 수 있습니다. 즉, 뒤에 등장한 \1은 첫번째 버퍼에 저장된 하위 표현식을 참조하겠다는 말과 같습니다. 이런 역참조를 통해, 반복되는 문자를 쉽게 찾을 수 있습니다. (참고로, 두자리 이상이 넘어가는 숫자에 해당하는 역참조가 존재하고 해당 그룹 숫자에 해당하는 그룹이 있을 경우 역참조로 간주되나, 아닐 경우에는 구문 분석 오류로 간주됩니다.)


확실한 이해를 위해 역참조 예제를 하나 더 보고, 분석해보도록 합시다.


Reg. Expression:

<H([1-6])>.*?</H\1>

Text:

<H1>Text</H1>

<H2>Text</H3>

<H3>Text</H3>

<H4>Text</H4>


위에 쓰인 정규 표현식을 살펴보시면, [1-6]란 문자 집합이 하위 표현식으로 묶였으며, *? (게으른 수량자)가 쓰였습니다. (지금 예제에서는 탐욕적 수량자를 사용해도 문제없이 일치가 되나(메타 문자 .는 줄바꿈 문자와는 일치가 되지 않기 때문에), 모든 글자를 일치 시켜버리는 탐욕적 수량자와는 달리 게으른 수량자를 사용하면 안전하다는 장점을 지니고 있습니다)


뒤를 이어서 보시면, 역참조가 쓰였음을 보실 수 있습니다. 즉, 앞과 뒤의 숫자가 일치해야만 한다는 겁니다. 텍스트 중 두번째 줄에 있는 문자열은 앞의 2와 뒤의 3이 일치하지 않습니다. 역참조가 정말 유용하죠? 역참조에 대한 설명은 여기까지 하도록 하고, 읽느라 수고하셨습니다. 다음 강좌에서는 전방 탐색과 후방 탐색에 다룰 예정입니다.