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) 치환하는 데 매우 유용하다.
'프로그래밍 놀이터 > Tips' 카테고리의 다른 글
[도서 정리] 10. 조건 달기 - 손에 잡히는 10분 정규 표현식 (0) | 2020.01.01 |
---|---|
[도서 정리] 9. 전방탐색과 후방탐색 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.31 |
[도서 정리] 7. 하위 표현식 사용하기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.29 |
[도서 정리] 6. 위치 찾기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.28 |
[도서 정리] 5. 반복 찾기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.27 |
댓글