c:\windows\abc.dll
위와 같은 문자열에서 c:는 드라이브명이고 \windows\는 디렉토리(또는 폴더)명이며 abc.dll은 파일명입니다. 이같은 문자열에서 드라이브명과 디렉토리명, 파일명을 따로 분리하는 정규식에 대해 알아볼까 합니다. 이를 조금만 응용하면 http://www.moneybook.co.kr/pages/blog_dev_note과 같은 URL에서 도메인만, 즉 www.moneybook.co.kr만 추출하는 것도 가능합니다.
참고로 유닉스나 리눅스에서는 드라이브라는 개념 자체가 없습니다. 물리적으로 여러 디스크를 장착하는 거야 물론 가능합니다만 이들을 각각의 드라이브로 액세스하는 게 아니라 특정 디렉토리와 마운트시켜서 사용하도록 되어 있습니다. 개념적으로는 디스크 뿐만이 아니라 모든 게 유닉스 계열의 운영체제에서는 다 파일입니다.
어느 프로그래밍 언어에서든 파일을 열고 닫는 코딩을 하다 보면 위의 문제에 봉착하게 됩니다. 사용자가 입력한, 또는 선택한 파일에서 디렉토리만 뽑아낸다든가 할 일은 자주 있기 때문입니다. 물론 프로그래밍 언어에서 제공하는 문자열 함수만 써서도 충분히 해결할 수 있습니다만 오늘은 정규식으로 풀어볼까 합니다.
드라이브명을 매치시키는 건 무쟈게 쉽습니다. 무조건 영문자 하나에 콜론이 붙은 형태니까요. 다만 윈도우즈 계열에서는 대소문자를 구분하니까 이것만 신경쓰면 됩니다.
[a-zA-Z]:
위와 같습니다. 역시 쉽죠? 문제는 폴더입니다. 이건 드라이브명만 추출하는 것과는 차원이 다른 문제입니다. 왜냐구요? 바로 전방 탐색, 후방 탐색에 관한 문제이기 때문입니다. 전후방 탐색을 간단하게 설명드리면 ‘찾고자 하는 문자열을 검색함에 있어 그 문자열의 앞(전방 탐색의 경우) 또는 뒤에 있는 문자열을 참조는 하되 그 문자열 자체는 검색 결과에 포함되지 않는 탐색’이 됩니다.
으으윽~ 설명이 더 어렵네요. 쓰고 나니 저도 무슨 말인지 모르겠다는... 역시 예를 봐야지요. 위의 c:\windows\abc.dll에서 디렉토리를 추출하자면 드라이브명이 반드시 참조돼야 합니다. 드라이브명이 끝나고 나서 이어지는 게 디렉토리니까요. 즉 디렉토리 추출의 기준점은 드라이브가 됩니다. 하지만 문제는 막상 ‘디렉토리만’ 추출하는 것입니다. 따라서 드라이브는 ‘참조하되 검색 결과에는 포함되지 말아야’ 합니다. 이처럼 검색 결과에 들어가지 않는다는 개념을 정규식에서는 ‘소비하지 않는다’라고 표현하기도 합니다.
아, 참 전방과 후방이라고 할 때의 전후 개념을 먼저 확실히 해둬야겠네요. 자칫 혼동할 수 있거든요. 전은 문자열의 진행 방향이고 후는 그 반대입니다. 우리가 흔히 ‘문장의 앞 부분’ 또는 어느 책의 앞 부분이라고 할 때는 이 반대가 되지요? 그러니 혼동할 수도 있다는 것입니다. 예를 들어볼게요.
abcdefg
위와 같은 문자열에서 g는 a보다 전방에 있습니다. 반대로 a는 g보다 후방에 있습니다. 위의 문자열 c:\windows\abc.dll에 있어서는 드라이브명이 가장 앞(에궁, 또 헷갈리네요)쪽에 있으니까 정규식의 표현대로라면 후방에 위치합니다. 따라서 이때는 후방 탐생에 해당합니다. 좌우당간, 불문곡직 정규식부터 보겠습니다.
(?<=[a-zA-Z]:).+
위에서 둥근 괄호 안에 들어 있는 것이 바로 후방 탐색 표현입니다. 그리고 ?<= 기호가 바로 후방 탐색을 지시하는 메타문자입니다. 전방 탐색 메타문자는 ?=입니다. 후방 탐색은 < 기호가 더 들어가 있습니다. 이 기호가 가리키는 방향이 바로 후방입니다.
아무튼 위의 정규식을 해석해 보면 ‘괄호 안에 들어 있는 드라이브명과 매치는 시키되 소비는 하지 말라. 그 뒤에는 아무 문자나 한 글자 이상 붙어 있어야 한다’가 됩니다. 결과적으로 매치되는 문자열은 \windows\abc.dll입니다. 파일명도 포함돼 있네요. 물론 빼야지요. 그 작업부터는 다음 회에서 하겠습니다.