본문 바로가기
프로그래밍 놀이터/Tips

[도서 정리] 8. 역참조 사용하기 - 손에 잡히는 10분 정규 표현식

by 돼지왕 왕돼지 2019. 12. 30.
반응형

8. 역참조 사용하기 - 손에 잡히는 10분 정규 표현식



* 역참조(backreferences) 이해하기


-

<h2>gamza</h4> 와 같은 녀석이 있을 때 올바르지 않은 포맷인데도

<[hH][1-6]>.*?<[hH][1-6]> 에 매핑된다.





* 역참조로 찾기


-

This is. block of of text,

several words here are are

repeated, and and they

should not be.


아래 패턴으로 중복 노출되는 단어들을 찾을 수 있다.

[ ]+(\w+)[ ]+\1


[ ]+ 는 공백이 하나 이상 연속되는 겨우 일치한다.

그 다음 \w+ 가 괄호로 감싸져 있음에 주목하자.

반복해 일치시키려고 하위 표현식을 사용한 것이 아니다.

반복해서 일치하는 부분도 없다.

여기서는 나중에 일치한 부분을 사용할 수 있도록 표시하여 구별하고자 하위 표현식을 사용했다.

이 패턴에서 마지막 부분인 \1은 앞서 일치한 하위 표현식을 참조함을 의미하고, 따라서 (\w+)와 일치한 문자는 \1과도 일치한다.



-

역참조라는 용어는 이런 항목들이 앞에 나온 표현을 역으로 가리킨다는 사실을 나타낸다.



-

\1은 패턴에서 처음 사용한 하위 표현식과 일치한다는 듯이다.

\2는 두번째, 그리고 \3은 세 번째 사용한 하위 표현식과 일치한다는 식이다.



-

안타깝게도 역참조 문법은 정규식 구현에 따라 크게 다르다.

자바스크립트는 역참조를 표시할 때 역슬래시를 사용하는데 이는 vi 에디터에서도 사용한다.

펄은 달러 기호를 사용하므로 \1 대신 $1 로 표시한다.


닷넷 정규식은 일치한 정보를 포함하도록 이름이 Groups 인 속성을 담은 객체를 반환하도록 한다.

따라서 match.Groups[1]은 C# 에서 가장 먼저 일치하는 부분을 참조하며, match.Groups(1)은 비주얼 베이직 닷넷에서 가장 먼저 일치하는 부분을 참조한다.

자바와 파이썬은 group 이라는 이름의 배열이 포함된 결과 객체(match object)를 반환한다.



-

역참조를 변수와 비슷하게 생각해도 된다.



-

header 예제를 고쳐보면..

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



-

역참조는 참조하는 표현식이 하위 표현식일 때만 동작할 것이다.



-

일치하는 부분을 참조하는 숫자는 주로 1로 시작한다.

많은 구현에서 0번째 참조라고 하면 표현식 전체를 가리킨다.



-

\1은 첫번째, \5는 다섯 번째 하는 식으로 상대적 위치로 참조된다.

이것은 일반적인 방식이지만, 이 문법에는 심각한 제약 사항이 하나 있다.

하위 표현식을 수정하거나 옮겨 하위 표현식 순서가 바뀌면 패턴이 깨질 수 있고, 하위 표현식을 추가하거나 삭제하면 문제를 해결하기가 훨씬 더 힘들어진다는 점이다.

이런 결점을 해결하고자 몇몇 새로운 정규식 구현들은 ‘이름 붙여 저장하기’ 기능을 지원하는데, 이 기능은 각 하위 표현식에 고유한 이름을 주어 상대적인 위치가 아니라 이 이름으로 하위 표현식을 참조하도록 한다.

‘이름 붙여 저장하기’는 널리 쓰이지 않고, 지원하는 구현마다 문법이 서로 다르기 때문에 이 책에서는 다루지 않는다.

하지만 만약 여러분이 닷넷처럼 이름을 붙여 저장하는 기능이 있는 환경을 쓴다면, 이 기능을 쓰는 것이 가장 좋다.





* 치환 작업 수행하기


-

단순한 텍스트를 치환하는 데 정규식은 필요 없다.

예를 들어 CA 를 모두 California 로 치환하거나, MI 를 Michigan 으로 치환하는 일은 단연코 정규식을 쓸 정도로 대단한 일이 아니다.

정규식을 써 치환하는 작업은 역참조와 함께 사용했을 대 진가를 발휘한다.



-

Hello, ben@forta.com is my email address.


이메일 주소를 찾는 정규식은 (\w+[\w\.]*@[\w\.]+\.\w+)

이 이메일에 a tag 를 씌우고 싶다면... <a href=“mailto:$1”>$1</a> 로 하면 된다.


치환 작업을 할 때는 정규 표현식이 두 개 필요하다.

하나는 원하는 부분을 일치시키는 패턴이고 다른 하나는 일치한 부분을 치환하는 데 사용할 패턴이다.

역참조는 서로 다른 패턴에서도 사용할 수 있으므로, 첫 패턴에서 일치한 하위 표현식을 두 번째 패턴에서도 쓸 수 있다.



-

정규식 구현에 따라 역참조를 표시하는 방법을 바꿔야 한다.

자바스크립트 사용자는 앞서 사용한 역슬러시 대신 달러 기호를 써야 한다. (위의 예제)



-

하위 표현식은 역참조를 사용해 필요한 만큼 여러 번 참조될 수 있다.



-

텍스트 형식을 바꿔야 할 때는 해당 텍스트를 여러 조각의 하위 표현식으로 작게 나누는 편이 유용할 때가 많다.

이렇게 하면 텍스트를 세밀하게 다룰 수 있는 여지가 더 커진다.



** 대소문자 변환하기


-

몇몇 정규식 구현에서는 아래 메타 문자를 써서 텍스트를 변환하도록 지원한다.


\E : \L 혹은 \U 변환의 끝을 나타낸다.

\l : 다음에 오는 글자를 소문자로 변환한다.

\L : \E를 만날 때까지 모든 문자를 소문자로 변환한다.

\u : 다음에 오는 글자를 대문자로 변환한다.

\U : \E를 만날 때까지 모든 문자를 대문자로 변환한다.



-

<h1> 으로 감싸진 문자를 모두 대문자로 변경하려면...


매치 : (<[Hh]1>)(.*)(<\/[hH]1>)

치환 : $1\U$2\E$3





* 요약


-

하위 표현식은 문자 집합이나 표현식을 정의하는 데 쓴다.

하위 표현식은 일치하는 부분을 반복해 찾는 작업에 사용할 수도 있고, 패턴 안에 참조될 수도 있다.

이런 참조를 역참조라고 부른다.

안타깝게도, 역참조 구문은 구현마다 차이가 있다.

역참조는 텍스트를 검색하고(match) 치환하는 데 매우 유용하다.




반응형

댓글