어떤 패턴을 기준으로 그 패턴과 일치하는 문자열을 찾고자 하는게 아니라, 그 패턴의 직전에 위치하는 문자열이나 직후에 위치하는 문자열을 찾고 싶을 때는 전후방탐색(look-around)을 사용하면 된다.
전후방탐색이란 어떤 문자열이 패턴에 일치하지만 이를 값으로 리턴하지 않는 정규표현식 패턴이다. 크게 전방탐색(look-ahead)과 후방탐색(look-behind)으로 나눌 수 있는데, 쉽게 말하면 각각의 기호 뒤에 위치하는 문자열을 기준으로 패턴을 앞쪽에서 탐색하는 것이 전방탐색, 뒷쪽에서 탐색하는 것이 후방탐색이다. 기준이 되는 문자열은 포함하지 않는다.
?=
뒤의 문자열을 바로 뒤에 가지고 있는 (=> 해당 문자열 직전까지)?<=
뒤의 문자열을 바로 앞에 가지고 있는 (=> 해당 문자열 직후부터)전방탐색의 기호는 ?=
이며, 기호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이다. 하위표현식과 동일하게 소괄호로 감싸주어야 한다.
전방탐색의 대표적인 예시인 URL에서 프로토콜만 추출하는 문제를 보자.
http://www.liankim.com
https://www.liankim.com
ftp://192.23.56.189
/^.+(?=:)/gm
^
: 문자열 맨 앞에 있고.+
: 한 글자 이상이고(?=:)
: 바로 뒤에 ':'이 있는-> 문자열 맨 앞에 있는 :
직전까지의 한 글자 이상의 문자열
후방탐색의 기호는 ?<=
이며, 기호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이다. 전방탐색 기호의 ?와 = 사이에 < 기호가 추가되었다. 마찬가지로 소괄호로 감싸주어야 한다.
같은 예제에서 후방탐색을 사용하여 도메인/ip 주소만 추출해보자
http://www.liankim.com
https://www.liankim.com
ftp://192.23.56.189
/(?<=\/{2}).+/gm
\/{2}
: /
가 두 번 연속되는(?<=\/{2})
: 바로 앞에 연속되는 두 개의 /
가 있는.+
: 한 글자 이상인 -> //
바로 뒤에 위치하는 한 글자 이상의 문자열
(예제는 도메인/ip 주소 이후 아무것도 존재하지 않으므로 뒷부분을 고려하지 않음)
http://www.liankim.com
https://www.liankim.com
ftp://192.23.56.189
전방탐색과 후방탐색을 같이 사용하면 후방탐색 기준 패턴과 전방탐색 기준 패턴 사이의 문자열을 찾을 수 있다.
전방탐색과 후방탐색을 같이 사용하여 HTML body에서 <li>
태그 안에 있는 문자열을 찾아보자.
<ul>
<li>kim</li>
<li>lian</li>
</ul>
/(?<=\<li\>).*(?=\<\/li\>)/gm
(?<=\<li\>)
: 앞에 <li>
가 있는.*
: 0자 이상인 (문자가 없거나 있거나 많거나)(?=\<\/li\>)
: 뒤에 </li>
가 있는-> <li>
와 </li>
사이에 위치하는 문자열
<ul>
<li>kim</li>
<li>lian</li>
</ul>