[정규표현식(Regular Expression) 정리] - 3. 전후방탐색(look-around)과 전방탐색(look-ahead)과 후방탐색(look-behind)

728x90
반응형

2021.12.02 - [SW/Reference] - [정규표현식(Regular Expression) 정리] - 2. 메타 문자와 플래그

 

[정규표현식(Regular Expression) 정리] - 2. 메타 문자와 플래그

2021.12.02 - [SW/Reference] - [정규표현식(Regular Expression) 정리] - 1. 기본 개념 [정규표현식(Regular Expression) 정리] - 1. 기본 개념 1. 서두 필자가 여러 블로그, 책을 더듬어가며 정리한 정규식 문법..

betaman-workshop.tistory.com

정규표현식의 메타문자와 플래그에 대해 잘 모르고있다면 이전글을 보고오길 바란다.


정규표현식 Regular Expression

1. 서두

이번 포스팅에서는 정규표현식에서 사용되는 "전후방탐색(look-around)"에 대해 설명할 예정이다.

(본 포스팅 시리즈는 Javascript 문법 내에서 사용되는 표준을 가져와 설명 중이다. 다른 언어도 크게 다르진 않는데 언어마다 사용성이 조금씩 다르기 때문에 다른언어에서 사용시엔 해당 언어의 정규표현식 사용법을 참고하여 사용하기 바란다.)

2. 전후방탐색(look-around)이란?

전후방탐색이란, "어떤 문자열이 패턴에 일치하지만 이를 값으로 리턴하지 않는 정규표현식 패턴"을 말하는데,
크게 "전방탐색(look-ahead)""후방탐색(look-behind)"이 있다.

전후방탐색의 사용예시를 보자면,
예를 들어 어떤 임의의 텍스트 안에 있는 모든 금액을 찾고 싶다면 아래와 같이 나타낼 수 있다.

/\d([\d,]?)+/g : 숫자로 시작하고 콤마 또는 모든 숫자로 조합되는 문자열을 포함한다.

하지만 모든 숫자가 금액은 아닐 수 있기 때문에 다음과 같이 바꿀 수 있다.

/(\d([\d,]?)+ *원)|(₩ *\d([\d,]?)+)/g : 위 예제에 맨 앞에 "₩"가 붙거나 맨 뒤에 "원"이 붙고 사이에 공백이 있을 수 있는 문자열을 포함한다.

이렇게 만들면 금액만 포함할 수 있겠지만 검색결과에 숫자뿐만 아니라 화폐 단위인 "원" 또는 "₩"까지 포함되게 된다. 만약 단위까지는 필요없거나 포함되선 안되는 경우엔 참 난감해진다. 하지만 이때 전후방탐색을 사용하면 이를 해결할 수 있다.

3. 전방탐색 (look-ahead)

전방탐색은 특정 문자 또는 문자열(패턴 문자열)을 기준으로 앞쪽(왼쪽)에 있고 패턴에 일치하는 문자열을 찾는 방법이다.
전방탐색 문법은 "?="로 시작하고 등호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이다. 기본적으로 하위표현식과 동일한 형식으로 작성된다.

전방탐색 문법: (?=패턴_문자열)

[예문]
100,000원
200 원

[정규표현식]
/\d([\d,]?)(?= *원)/g : 숫자로 시작하고 콤마 또는 모든 숫자로 조합되고 뒤에 " *원" (공백문자 0개 이상과 "원"이 있는 패턴)이 붙고 그 사이에 공백이 있을 수 있는 문자열 (플래그 옵션: 패턴에 모두 일치하는 결과만 반환)
(결과값에는 " *원"이 포함되지 않고 " *원" 앞에 있는 문자열만 포함된다)

[결과]
100,000
200

이러한 전방탐색의 대표적인 사용예시로 URL에서 프로토콜만 찾아내야 상항이 있다.

[예문]
http://www.helloworld.com
https://www.helloworld.com
ftp://file.helloworld.com
위 URL에서 프로토콜만 검출하자

[정규표현식]
/^.*(?=:)/ 
: 문자열 맨 앞에 있고 뒤에 콜론이 붙는 길이가 0 이상인 문자열

[결과]
http://www.helloworld.com
https://www.helloworld.com
ftp://file.helloworld.com

4. 후방 탐색

전방탐색은 특정 문자 또는 문자열(패턴 문자열)을 기준으로 뒤쪽(오른쪽)에 있고 패턴에 일치하는 문자열을 찾는 방법이다.
후방탐색 문법은 "?<="로 시작하고 등호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이다. 기본적으로 하위표현식과 동일한 형식으로 작성된다.

전방탐색 문법: (?=패턴_문자열)

[예문]
₩ 100,000
₩200

[정규표현식]
/(?<=₩ *)\d([\d,]?)+/g : 맨 앞에 패턴 문자열 "\ *" ("\"문자와 공백이 0개이상 있는 패턴) 뒤에 있는 숫자로 시작하고 콤마 또는 모든 숫자로 조합의 문자열 (플래그 옵션: 패턴에 모두 일치하는 결과만 반환)
(결과값에는 "\ *"가 포함되지 않고 "\ *" 뒤에 있는 문자열만 포함된다)

[결과]
100,000
200

근데 주의할 부분은 오래된 버전의 자바스크립트 엔진에서는 긍정형 전방탐색이 동작하지 않는다. IE 11에서는 오류가 발생하지만 크롬에서는 문제는 없다. Node.js의 경우 8.9.4 버전에서 'invaild group' 오류가 나타나지만 이후 버전에선 해결된 것으로 보인다.

5. 전방탐색 + 후방탐색

전방탐색과 후방탐색을 같이 사용하면 맨 앞의 기준 패턴문자열과 맨 뒤의 기분 패턴문자열 사이의 문자열을 찾을 수 있다.

예를 들면 HTML 태그 중 <title>태그 안에 있는 문자열을 찾아낸다고 하면,

[예문]
<html lang="ko">
  <head>
    <title>hello world</title>
  </head>
</html>

[정규표현식]
/(?<=\<title\>).*(?=\<\/title\>)/gm
: "<title>"과 "</title>" 사이의 문자열 (플래그 옵션: 패턴에 모두 일치하는 결과만 반환, 멀티라인)

[결과]
<html lang="ko">
  <head>
    <title>hello world</title>
  </head>
</html>

6. 부정형 전후방 탐색

부정형 전후방탐색은 말그대로 부정형 전방탐색과 부정형 후방탐색을 합쳐서 말한 것이다.
부정형은 말 그대로 기본 전후방탐색을 반대로 생각하면 된다. 기본 전후방탐색의 "="를 "!"로 변경하면 부정형이 된다.

부정형 전방탐색은 "?!"로 시작하고 등호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이고, 문자열 뒤에 기준 문자열이 붙지 않는 문자열을 찾는 방법이다.

부정형 전방탐색 문법: (?!패턴_문자열)

[예문]
100
100 원
단위가 붙지 않은 숫자만 검색

[정규표현식]
/\d+\b(?!원)/
: 뒤에 " *원"이 붙지 않는 모든 숫자 조합의 문자열

[결과]
100
100 원

부정형 후방탐색은 "?<!"로 시작하고 등호 다음에 기준이 될 패턴 문자열이 오는 하위표현식이고, 문자열 앞에 기준 문자열이 붙지 않는 문자열을 찾는 방법이다.

부정형 후방탐색 문법: (?<!패턴_문자열)

[예문]
100
₩ 100
단위가 붙지 않은 숫자만 검색

[정규표현식]
/\b(?<!₩ *)\d/ 
: 앞에 "₩ *"이 붙지 않은 모든 숫자 조합의 문자열

[결과]
100
₩ 100
728x90
반응형