정규표현식 lookbehind에 대해 알아봅시다.

REGEX 2022. 11. 3. 01:00

 저번 시간에 lookahead에 대해 배웠습니다. 이번 시간에는 정규표현식 lookbehind에 대해 배워봅시다.

 


 먼저 (?<=foo)를 입력해 봅시다. 저번 시간에는 (?=foo)를 입력했는데요. ?와 = 사이에 <가 들어갔어요. 이게 무엇을 의미하는지 파악해 봅시다.

 

 

 기준선이 5개가 잡히는데요. 2번째, 3번째, 4번째, 5번째, 6번째 f 앞에 기준선이 잡혀있음을 알 수 있어요. 이 기준선들의 공통점을 보면, 기준선 앞에 foo 라는 패턴이 매치됨을 알 수 있어요. 예를 들자면, 2번째로 잡힌 기준선을 봅시다.

 

 

 이 기준선 앞에는 foo가 잡혀요. 제가 드래그 한 부분을 의미합니다. 그런데, 1번째 f 앞에는 어떨까요? 이것을 기준으로 잡히는 문자가 없어요. 빈 문자열은 foo 패턴에 match 되지 않기 때문에, 1번째 f 앞에 기준선이 잡히지 않아요. 즉 foo라는 패턴이 있으면, 그 패턴 앞에 기준선이 잡히는 것이 lookahead라면, 패턴 뒤에 잡히는 것이 lookbehind인 셈입니다.

 

 

 이제 (?<!o)를 봅시다. 패턴 o가 매치되지 않는 lookbehind인데요. 기준선 앞에 o가 잡히지 않으면 됩니다.

 

 

 그러면, 기준선 앞에 빈 문자열이 오는 경우와, 기준선 앞에 f가 오는 경우가 있겠습니다. 7개가 잡히는 것 확인하실 수 있어요.

 

 


 이제 예제들을 보겠습니다. 먼저 target string은 "ab12cd34ef56" 입니다.

 

 (?<=[a-z])(?=[0-9])입니다. lookahead와 lookbehind는 어떠한 문자도 소모하지 않는다는 것도 기억하면서 보도록 하겠습니다. 먼저, 앞에 나온 (?<=[a-z])부터 봅시다. 이것은 기준선이 있으면 앞에 소문자가 와야 해요. 그러한 기준선들을 찾아야 해요.

 

 

 요래 6개가 나와요. 예를 들어 6번째 분홍색 기준선 앞에는 f가 옵니다. 여기까지 이해가 가시나요? 다음에 (?=[0-9])가 나오는데요. 일단, (?=[0-9])를 만족하는 기준선부터 구해 봅시다. (?<=..)와 다르게 (?=..)는 기준선 뒤에 따라붙는 패턴을 가지고 판단한다고 했어요. 패턴이 [0-9]입니다. 즉, 기준선이 있으면 뒤에 숫자가 와야 해요. 그러한 기준선들을 찾아야 합니다.

 

 

 역시 6개입니다. 이 2개의 lookahead와 lookbehind만 있었으니, 그 사이에 어떠한 문자도 소비되지 않았습니다. 즉, 기준선 하나에 대해 lookahead 조건도 만족시키고 lookbehind 조건도 만족해야 하는데요. 기준선 앞에는 소문자가, 뒤에는 숫자가 오는 경우를 찾으면 됩니다.

 

 

 그러면 b와 1사이, d와 3사이, f와 5사이가 되겠네요. 혹은 위에 lookahead의 기준선과 lookbehind의 기준선의 교집합을 구해도 큰 문제는 없겠습니다.

 

 

 다음 예제는 "abbyefoo56bfoof"입니다. 찾을 내용에 (?<=[a-z])foo(?=[0-9])를 입력해 보겠습니다. 그러면 어떻게 결과가 나올까요? 무언가 복잡해 보이는데요. 하나씩 천천히 해 봅시다. 먼저 해당 문자열에서 (?<=[a-z])가 매치되는 기준선부터 찾아봅시다.

 

 

 이제 이 기준선 다음에 foo가 매치되는 패턴을 찾아봅시다. foo 앞에 기준선과, 뒤에 따라오는 foo 앞에 있는 기준선 요래 2개입니다.

 

 foo 때문에 문자가 3개 소비되었습니다. 그러면, 제가 드래그 한 것 뒤에 오는 패턴이 숫자인 것만 찾으면 되는데요. 앞에 foo입니다. 따라서, 앞에 있는 foo만 매치됩니다. 아래 그림이 이를 보여줍니다.

 

 

 간단했나요?