9. 전방탐색과 후방탐색 - 손에 잡히는 10분 정규 표현식 |
-
지금까지 사용한 표현식들은 모두 일치하는 텍스트를 가지고 있었지만, 가끔은 텍스트 자체를 찾기보다는 어디서 텍스트를 찾을지를 표시하는데 표현식을 쓰고 싶을 때도 있다.
그러려면 전후방탐색(lookaround)을 써야 한다.
* 전후방탐색 살펴보기
-
전방탐색은 모든 주요 정규식 구현에서 지원하지만, 후방탐색은 광범위하게 지원하지 않는다.
자바, 닷넷, PHP, 파이썬, 펄에서는 몇 가지 제약이 있지만 후방탐색을 지원한다.
자바스크립트에서는 지원하지 않는다.
* 전방탐색 - 앞으로 찾기
-
전방탐색(lookahead) 패턴은 일치 영역을 발견해도 그 값을 반환하지 않는 패턴을 말한다.
전방탐색은 실제로는 하위 표현식이며, 하위 표현식과 같은 형식으로 작성한다.
전방탐색 패턴의 구문은 ?=로 시작하고 등호(=) 다음에 일치한 텍스트가 오는 하위 표현식이다.
-
일부 정규식 문서에서는 일치하는 영역을 반환하는 동작을 표현할 때 '소비한다(consume)'는 용어를 쓴다.
이럴 경우 전방탐색은 ‘소비하지 않는다(not consumed)’고 말한다.
-
http://www.naver.com/
https://mail.naver.com/
ftp://ftp.naver.com/
.+(?=:)
위 정규식을 적용하면 프로토콜 영역만 추출해 올 수 있다. ( : 는 매칭은 하지만 찾은 범위로 표시되지 않는다. )
-
전방탐색(후방탐색) 일치는 실제로 결과를 반환하지만, 반환된 문자의 길이가 항상 0이다.
따라서 전방탐색을 흔히 ‘제로 폭(zero-width)’이라 부르기도 한다.
-
모든 하위 표현식 앞쪽에 단순히 ?=를 붙이기만 하면 전방탐색 표현으로 바꿀 수 있다.
하나의 검색 패턴 속에서 여러 개의 전방탐색 표현식을 사용할 수 있고, 또한 그 표현식은 패턴 안에서 어느 위치에서든 사용할 수 있다.
앞에서 본 예제처럼 하위 표현식의 제일 앞에 오지 않아도 된다.
* 후방탐색 - 뒤로 찾기
-
?= 는 앞으로 탐색한다.
일치하는 텍스트 다음에 무엇이 오는지 찾고, 발견한 텍스트 자체는 소비하지(consume) 않는다.
따라서 ?= 는 전방탐색 연산자라 부른다.
많은 정규식 구현에서 전방탐색과 더불어 후방탐색(lookbehind) 기능도 지원한다.
텍스트를 반환하기 전에 탐색하는 작업은 뒤쪽을 탐색하기도 포함한다.
후방탐색 연산자는 ?<= 이다.
-
?<= 는 ?= 와 사용 방법이 같다.
즉, 하위 표현식 안에서 사용하고, 일치할 텍스트 앞에 온다.
-
아래 예제에서 가격만 뽑고 싶다면
ABC01: $23.45
HGG42: $5.31
CFMX1: $899.00
\$[0-9.]+ 정규식을 대입할 수 있다.
그러나 숫자만 뽑고 싶다면..
(?<=\$)[0-9].+
-
전방탐색 패턴은 마침표(.)와 더하기(+)를 포함하여 텍스트의 길이를 다양하게 일치시킬 수 있으며, 매우 동적이다.
반대로 후방탐색 패턴은 보통 일치시킬 텍스트의 길이를 고정해야 한다.
거의 모든 정규식 구현에는 이런 제약이 있다.
* 전방탐색과 후방탐색 함께 사용하기
-
<head>
<title>Gamza homepage</title>
</head>
여기서 title 내용을 뽑고 싶다면...
(?<=<[Tt][Ii][Tt][Ll][Ee]>).*(?=<\/[Tt][Ii][Tt][Ll][Ee]>)
* 부정형 전후방탐색
-
후방탐색과 전방탐색은 반환할 텍스트의 위치, 즉 찾고자 하는 부분의 앞뒤를 특별히 지정하고 싶을 때 주로 사용했다.
이런 방법들을 긍정형 전방탐색과 긍정형 후방탐색이라고 한다.
긍정(positive)이라는 말을 쓰는 이유는 실제로 일치하는 텍스트를 찾기 때문이다.
-
전후방탐색 중에서 부정형(negative) 전후방탐색은 비교적 덜 쓰는 방법이다.
부정형 전방탐색은 앞쪽에서 지정한 패턴과 일치하지 않는 텍스트를 찾고, 부정형 후방탐색도 이와 비슷하게, 뒤쪽에서 지정한 패턴과 일치하지 않는 텍스트를 찾는다.
-
(?=) : 긍정형 전방 탐색
(?!) : 부정형 전방 탐색
(?<=) : 긍정형 후방탐색
(?<!) : 부정형 후방탐색
-
대개 전방탐색을 지원하는 정규식 구현은 긍정형과 부정형 전방탐색을 모두 지원한다.
마찬가지로 후방탐색을 지원하는 구현에서도 긍정형과 부정형 후방탐색 모두 지원한다.
-
I paid $30 for 100 apples.
여기서 $ 를 제외한 가격 숫자를 찾으려면...
(?=\$)\d+
갯수 숫자를 찾으려면....
\b(?!\$)\d+\b
여기서 \b 가 들어간 이유는… $30 의 0 이 찾아지기 때문이다.
* 요약
-
전방탐색과 후방탐색을 사용하면, 무엇을 반환할지 더 구체적으로 명시할 수 있다.
전후방탐색 명령어는 하위 표현식을 통해 텍스트의 위치를 지정하지만, 소비하지는 않는다.
일치하지만, 일치한 텍스트 자체에는 포함하지 않는다는 이야기다.
긍정형 전방탐색을 (?=)로 정의하고, 부정형 전방탐색은 (?!)로 정의한다.
몇몇 정규식 구현에서는 (?<=)로 긍정형 후방탐색을 지원하고, (?<!)로 부정형 후방탐색을 지원한다.
'프로그래밍 놀이터 > Tips' 카테고리의 다른 글
[도서 정리] 11. 정규 표현식으로 해결하는 일반적인 문제들 - 손에 잡히는 10분 정규 표현식 (0) | 2020.01.02 |
---|---|
[도서 정리] 10. 조건 달기 - 손에 잡히는 10분 정규 표현식 (0) | 2020.01.01 |
[도서 정리] 8. 역참조 사용하기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.30 |
[도서 정리] 7. 하위 표현식 사용하기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.29 |
[도서 정리] 6. 위치 찾기 - 손에 잡히는 10분 정규 표현식 (0) | 2019.12.28 |
댓글