정규식 양방탐색과의 만남

햄도·2021년 3월 10일
0

?<!

정규식은 기초만 한 번 훑어본 상태였는데, 로직 수정을 요청받아 열어본 코드에 생소한 정규식이 있었다.

reg = '(?<![a-z])(..중략..)'

구글은 특수문자 검색도 안돼서 regex less than bracket after question mark 따위의 검색어로 저게 뭔지 겨우 찾았다.

정규식에는 정규식과 같은패턴을 찾는 기능뿐만 아니라, 찾는 패턴 앞뒤를 체크해 특정 패턴이 앞이나 뒤에 나오는 경우/나오지 않는 경우에만 패턴 매칭을 하도록 해주는 기능도 있다. 이런 기능을 한국어로는 양방탐색이라고 하고, 영어로는 lookaround라고 하는 것 같다.

양방탐색에는 네 가지 종류가 있다.

  • 긍정 전방탐색 (?=<regex>)
  • 긍정 후방탐색 (?<=<regex>)
  • 부정 전방탐색 (?!<regex>)
  • 부정 후방탐색 (?<!<regex>)

긍정이란 regex와 일치할 때 매칭하는 조건이고, 부정은 반대로 regex와 일치하지 않아야 매칭하는 조건이다. 전방은 패턴의 오른쪽, 후방은 패턴의 왼쪽을 체크한다.

즉 긍정 전방탐색, 긍정 후방탐색은 패턴의 앞이나 뒤에 어떤 패턴이 등장해야 매칭하고 싶을 때 사용하며, 부정 전방탐색, 부정 후방탐색은 패턴의 앞이나 뒤에 어떤 패턴이 등장하지 않아야 할 때 사용한다.

이러한 양방탐색 조건은 결과 문자열로 뽑히지 않는다. 예시를 확인해보자.

q(?=u)

위 정규식은 뒤에 u가 있는 q에 대해서만 매칭한다. query라는 단어가 있다면 이 중 q만 결과 문자열이 된다.

(?<=a)b

위 정규식은 a 뒤에 있는 b에 대해서만 매칭한다. cab의 b에는 매칭하지만 bed나 debt의 b에는 매칭하지 않는다.

여러 개의 패턴에 대해서 양방탐색을 수행하고 싶은 경우 여러 표현식을 붙이면 된다.

(?<!a)(?<!b)b

위와 같이 작성하는 경우 b가 a나 b 뒤에 있지 않을 때만 매칭한다. 간단한 패턴이기 때문에 굳이 양방탐색을 사용할 필요는 없어보이지만 조건이 복잡해지면 꽤 유용하다.

참고

profile
developer hamdoe

0개의 댓글