정규표현식을 공부하면서 기본적인 것이지만,
이해 및 인식이 잘 되지 않아 헤매고 있는 것이
따라서 간단히 정리하겠습니다.
룩어라운드는 단어 경계를 나타내는 메타 문자인 [/b]나
앵커인 [^](문자열 앞), [$](문자열 끝)와 마찬가지로
텍스트에 매치되지 않고 텍스트 안에 있는 어떤 위치에 매치된다.
예제 1
문자열 : "see Jeffs book"
정규식 : s/\bJeff(?=s\b)/Jeff`/g
위 정규식은 'Jeffs'를 'Jeff`s'로 바꾸고자 할 때 쓰입니다.
그리 실용적이지는 못하지만,
룩어라운드의 일부분인 긍정형 룩어헤드(positive lookahead)의 훌륭한 예입니다.
살펴보면 다음과 같습니다.
'[단어경계]Jeff'를 맞춘 후 룩어헤드를 시도합니다.
룩어헤드는 그 위치(Jeff 다음 위치)에서 's[단어경계]'이 맞는 경우
전체적으로 정규식에 맞는 문자열이 됩니다.
하지만 여기서 실제 매치되는 부분은 Jeff뿐이고,
나머지(s\b)는 위치를 선택하는 부분입니다.
다시 말하자면 'Jeff'만 매치하는 척 하면서 실제로는 'Jeffs'를 모두 체크합니다.'
예제 2
문자열 : "by Jeffrey Friedl, Jeffley, Jeff, Jefferson"
정규식 : (?=Jeffrey)Jeff
위 정규식은 문자열의 Jeffrey의 Jeff에 일치합니다.
하지만 Jeff, Jefferson에는 일치하지 않습니다.
왜냐하면 앞의 룩어헤드가 있기 때문입니다.
살펴보면 다음과 같습니다.
'Jeffrey를 찾아 맞춘 후 실제 매치는 Jeff만 한다.'
따라서 다음과 같은 정규식을 실행시키면 다음과 같습니다.
바뀐 부분을 보면 'Jeffrey'가 'NoSyurey'로 바뀌어져 있습니다.
(영어학원에서 쓰는 저의 닉네임이 Jeff라서 이렇게 하였습니다.)
위에서 얘기했듯이 다른 Jeff는 변하지 않았습니다.
그리고 'Jeffrey'를 찾았지만, 'NoSyu'라 바뀌는 것은 'Jeffrey'의 'Jeff'뿐입니다.
참고로 '(?=Jeffrey)Jeff'와 'Jeff(?=rey)'는 같습니다.
예제 3
문자열 : 1234567890
정규식 : s/(?<=\d)(?=(\d\d\d)+$)/,/g
위 정규식은 숫자를 끊어읽기 위해 세자리수마다 쉼표를 찍게합니다.
살펴보면 다음과 같습니다.
왼쪽에 숫자가 하나 존재하고,
오른쪽에 있는 숫자의 개수가 3의 배수인 경우입니다.
(+는 하나 그 이상 반복함을 의미합니다.)
따라서 위의 문자열에 해당 정규식을 실행시키면
1,234,567,890라고 찍힙니다.
정리하면 다음과 같습니다.
(?<=.....) : 긍정형 룩비하인드 - 하위 표현식(..... 부분)이 왼쪽에 매치될 때
(?<!.....) : 부정형 룩비하인드 - 하위 표현식(..... 부분)이 왼쪽에 매치되지 않을 때
(?=.....) : 긍정형 룩어헤드 - 하위 표현식(..... 부분)이 오른쪽에 매치될 때
(?!.....) : 부정형 룩어헤드 - 하위 표현식(..... 부분)이 오른쪽에 매치되지 않을 때
긍정형(positive), 부정형(negative),
룩어비하인드(lookbehind), 룩어헤드(lookahead)
여기서 왼쪽과 오른쪽은 문자와 문자 사이라는 해석이 맞을 듯싶습니다.
(문자라기보다는 정규표현식이 다루는 원자(더 이상 쪼갤 수 없음)의 개념이겠지만...)
저는 이렇게 이해하였습니다.
예제 3번에서 '1,234'부분을 보면 원래 '1234'입니다.
여기서 1과 2사이를 기준으로 왼쪽은 숫자 하나(1)가 있고,
오른쪽은 숫자가 문자열 끝에서 3의 배수로 묶여있습니다.(234)
따라서 그 자리(1과 2사이)에 ','을 집어넣은 것입니다.
이처럼 문자와 문자 사이를 기준으로
왼쪽 혹은 오른쪽에 매치 혹은 매치 안됨을 점검하는 것이
룩어라운드(lookaround)인 듯싶습니다.
하지만 실제로 매치가 되는 것이 아니라 그 자리만을 알려줍니다.
그래서 'Jeffley'가 'NoSyu'가 된 것이 아니라 'NoSyuley'가 된 것입니다. (예제 2)
참고 예제
단어의 시작과 끝 : '(?<!\w)(?=\)', '(?<=\w)(?!\w)'
HTML <B>태그 : '<B>((?!</B>).)*</B>'
참조
정규 표현식 완전 해부와 실습 Page 99~110
- UTF8 Perl 소스, 명령 프롬프트(cmd.exe)에서 한... (2)2009/01/10
- C에서 가변 배열(Variable-Length Array) (8)2008/03/22
- 정규표현식 |은 순서대로 매치 (2)2007/11/28
- 정규표현식 룩어라운드(lookaround) (3)2007/11/26
- UTF8 Perl 소스, 명령 프롬프트(cmd.exe)에서 한... (7)2007/09/29
- 이글루 백업 프로그램 - 배포는 어떻게 하지? (10)2007/09/29
- NoSyu에게 있어 프로그래밍의 시작과 끝 (2)2007/09/27
글에 잘못된 점, 다른 점, 부족한 점이 있다면 지적해주세요.
댓글, 트랙백, 메일 모두 고맙습니다.
트랙백 주소 :: http://nosyu.pe.kr/trackback/1139
-
Subject: 정규 표현식 완전 해부와 실습 -서환수 역
Tracked from 김재호의 디지털보단 아날로그 2009/02/20 08:31 삭제정규 표현식 완전 해부와 실습 - 제프리 프리들 지음, 서환수 옮김/한빛미디어 최근 한 달여 동안 침대에서 이 책과 함께 잠이들곤 했다. 이 책은 정규표현식을 다루는 최고의 명서이다. 인터넷을 둘러보다 보면 정규 표현식을 설명하는 많은 문서들에서 언제나 빠짐없이 등장하는 단 한권의 책이다. -거의 모든 문서들에서 많은 정규식 책들 중 오직 이 책만을 추천하고 있을 정도로 이 책의 위상은 독보적이다. 이 책은 3판(2006)까지 나와있는데, 우리말로..







댓글을 달아 주세요
참 지금까지 정규표현식을 모르고 지냈다는게 바보같이 느껴진다.
요즘에 정규표현식 완전 해부와 실습 책을 구할 수가 없어서 pdf파일 구해서 보고 있어 ㅋㅋ
지금 룩어라운드 부정형 보고 있는데 ㅋㅋ
2007년 11월에 쓴거면 벌써 다 땠겠는데?
>_< 정규 표현식 마스터하는 그날까지!!
오랜만..?^^;;;
정규표현식의 경우 배울 때는 별 생각없이 배웠지만....
정확하게는 Perl을 배우면서 정규표현식을 배우면 좋다고 하고,
너무 간단하게 설명하여 제대로 배워보자는 생각에 책을 구입하고 공부했던 것...^^
하지만 그 뒤로 거의 쓰지 않다보니
(가끔 문서 작업할 때 문자열 변경할 때?)
저기서 배운 것 거의 다 까먹었음..^^;;;
룩어라운드도 무엇이었나 헷갈리는 중....ㅜ