콘텐츠로 건너뛰기
Home » 20071111 : notepad++ 과 정규표현식

20071111 : notepad++ 과 정규표현식

[update] : 정규식 관련하여 근 10년만에 기초적인 내용을 이 글보다 조금 더 체계적으로 정리한 포스트를 발행하였으니, 아래 글 보다는 새 글을 먼저 읽어 보실 것을 권합니다.
지난 글에서는 소개하지 못한 notepad++의 기능 중 찾기/바꾸기에서 정규 표현식을 사용하는 법에 대한 이야기를 조금 하고자 합니다.
최근엔 html 코딩을 거의 하지 않고 (좀 해야할텐데) 있지만, 엑셀 문서의 내용을 미리 텍스트 파일로 만든다던가, 콘솔박스로부터 가져온 로그에서 필요한 자료를 추출하는데 있어서 notepad 의 덕을 톡톡히 보고 있습니다. 물론 회사 노트북은 주로 개발자들이 많이 사용하므로 Ultra Edit나 Edit Plus와 같은 보다 널리 알려진 편집기들이 설치가 되어 있습니다만, 개인적으로 뭔가 복잡해보이는 UI를 가진 이런 편집기보다는 깔끔해보이는 notepad++가 훨씬 더 사랑스럽더군요. 뿐만 아니라 무설치버전을 그냥 USB 메모리에 넣어다니면서 간단히 사용할 수 있다는 장점도 있고 해서 계속 notepad++를 고집중입니다.
그리하여 오늘 소개하려는 내용은 정규표현식을 사용하여 텍스트를 손보는 내용입니다. 그럼 정규표현식은 뭔가요?하고 물어야 정상입니다. 스크립트나 프로그래밍에 익숙한 분이시라면 그래도 어느정도 정규표현식에 익숙하시리라 생각이 됩니다. 하지만 대략 정규표현식이 무엇인지 모르는 블로거들이 더더더욱 많을 것으로 생각되니, 정규 표현식에 대한 간략한 설명이 필요할 듯 합니다.

정규표현식이란

정규표현식은 특정한 문자열을 쉽고 간단한 방법으로 찾아내기 위한 표현식입니다. 정규표현식은 현재까지 표준화된 하나의 통일안이 있는 듯 하지는 않습니다. 대표적으로 Perl 언어가 정규표현식을 지원하는 것으로 알고 있습니다. 또한 리눅스의 강력한(강력하다고 소문난) grep 라는 텍스트 필터 툴에서도 정규표현식을 지원합니다. 그 중 notepad의 정규표현식은 Scintilla의 그것을 거의 그대로 받아들였으며, 이는 펄에서 지원하는 정규식과 그 사용법이 매우 흡사합니다. 참고로 firefox의 국민 확장기능인 Adblock[adblock plus]는 자바스크립트와 비슷한 정규식을 사용하며, UltraEdit의 경우에는 grep와 비슷한 정규식을 사용하는 것으로 알고 있습니다.

Notepad 정규표현식의 문법

물론 여기에서 모든 걸 다 설명할 수는 없지만 몇 가지만 알려드리도록 하겠습니다. 정규표현식 자체는 일반 문자열의 매치를 포함하여, 이를 축약하여 이의 변형까지 함께 찾을 수 있도록 합니다. 참고로 백슬래시는 한글로 인코딩된 페이지에서는 (원화표시)로 보이게 됩니다.

  • ^: 행의 시작을 가리킵니다. 곧 숫자로 시작하는 행은 다음과 같이 표현됩니다.
    • ^d.+
  • [] : 대괄호는 포함된 문자들 중 하나와 매치하는 문자를 나타냅니다. 즉 [abc]라고 쓰면 a, b, c 중의 한 글자라고 보면 됩니다. 물론 [a-z]와 같이 하이픈을 넣어서 범위 전체를 지정해줄 수 있습니다.
    • [0-9]라고 적으면 한 글자의 숫자를 뜻합니다.
  • [^abc]: []속에 들어간 ^표시는 이 대괄호에 포함된 글씨는 제외한다는 뜻입니다.
    • S[^cde]m 이라는 정규식은 Sam, Sbm은 매치하지만 Scm, Sdm은 매치하지 않습니다.
  • $ : 행의 끝을 말합니다.즉 숫자로 끝나는 행은 ^.+[0-9]$와 같이 표현합니다.
  • . : 마침표는 임의의 한 글자에 해당합니다.
  • +:어떤 문자 뒤에 붙어서 해당하는 문자가 1개 이상, 여러 개라는 뜻입니다.
    • d+라고 하면 1, 123141, 2513452345234등 길이에 무관하게 연속된 숫자를 찾습니다.
  • * :X와 비슷하게 어떤 문자 뒤에 붙어서 그 문자가 0개 이상이라는 뜻을 나타냅니다. +는 그 문자가 반드시 한번은나오지만 *는 문자가 나오지 않아도 상관없습니다.
    • sa+m은 sam, saam, saaaaaam에 매치됩니다만 sm에는 매치되지 않습니다. 하지만 sa*m은 sm에도 매치됩니다.
  • \d : 한 글자의 숫자를 말합니다. (digit) [0-9]와 같습니다.
  • \w : 한 글자의 문자로 영문대소문자 및 숫자와 밑줄에 해당합니다.. [a-zA-Z0-9_]와 같습니다.
  • \s : 한 칸의 공백을 의미합니다.
  • \: 백 슬래쉬는 이스케이프 문자를 뜻합니다. 즉 ^, [, .과 같은 특수한 의미를 가지는 문자들을 글자 그대로 찾을 때 사용합니다.
    • \[abc\]라고 입력하면 a,b,c 중의 한 글자가 아닌 [abc] 자체에 매치됩니다.

보다 더 상세한 설명은 notepad++ 홈페이지(영문)에서 살펴볼 수 있습니다. 영문으로 설명이 되어 있지만 설명 자체가 쉽고 간단하며 예제와 함께 살펴보면 금방 이해할 수 있으리라 생각됩니다.

예제를 통해 살펴봅시다.

예제를 머리 써서 만들기 보다는 실제로 숩이 사용하는 방법을 예로 들어보려고 합니다. 콘솔박스를 통해 수집된 로그를 (어디서부터 받은 로그인지는 비밀) 토대로 메모리 사용량에 대한 정보를 추출합니다. 사실 콘솔 박스로부터 수집되는 정보는 상당히 다양하지만 메모리 정보를 담고 있는 부분은 아래와 같은 형식으로 되어 있습니다.

[21:44:07 Oct 12 Fri] @0x3924004E|JVM| Free Memory: Heap [ 2368340/ 6291456], Native[ 7299824/32505856]

우선 로그파일 전체를 notepad++로 불러들어와서 찾기(ctrl+F)를 실행합니다. 우리는 위와 같은행을 모두 찾아서 추출해야합니다. 통상 ‘Free Memory:’ 로 검색해도 무리가 없겠습니다만, 종종 중간에 정보가 끊어지고 2행에 걸쳐 깨진 채로 정보가 남는 경우가 있기 때문에, 그러한 행들은 찾아서는 안되겠습니다. 따라서 heap과 native 정보를 모두 포함하고 ‘숫자]‘로 끝나는 행을 찾아야겠지요. 이러한 정보는 다음과 같은 정규식을 통해 찾을 수 있습니다.

heap.+native.+d]$

아래 스크린샷과 같이 ‘정규표현식’에 체크를 해주고 위의 정규식을 입력한 다음, ‘열려진 파일에서 모두 찾기’ 버튼을 클릭합니다. 버튼을 클릭하면 notepad++아래쪽으로 분할창이 생성되며 해당하는 행들이 모두 찾아집니다.

그럼 새 파일을 하나 만들고, 아래의 내용을 모두 선택(Ctrl+A)하여 새 파일에 붙여 넣습니다.
이제 만들어진 식을 모두 요리할 차례입니다. 타임스탬프가 필요한 경우도 있고 그렇지 않은 경우도 있지만, 여기에서는 타임 스탬프를 포함하여 데이터를 정리하는 방법을 살펴보겠습니다. 그러기 위해서는 정규식의 패턴에 대해 살짝 살펴보아야 할 듯 합니다.

정규표현식의 패턴

여기서는 패턴이라고 했는데 사실 ‘그룹’이 올바른 표현입니다. (2017.07.12)

정규표현식의 패턴은 사실 ‘찾기’ 보다는 ‘바꾸기’에 더 적합한 방법입니다. 예를 들어 ‘Tom Smith’라는 이름의 표현을 “Smith, Tom”과 같이 바꾸고 싶다면 어떻게 해야할까요? 단지 바꿀 이름이 하나가 아니라 굉장히 많은 고객 명단이라든가 그런 것들이라면 난감하겠죠. (단지 이런 경우라면 텍스트 파일을 엑셀로 불러들여서 공백으로 나누어 바꾸는 용자들도 존재합니다. 좋은 아이디어죠.)
이런 경우에 패턴을 사용합니다. notepad의 패턴 사용은 간단합니다. 패턴이 되는 부분을 () 괄호로 묶은 다음, 바꿀 단어에서 \1, \2와 같이 나온 순서대로 써주면 되는 것이죠. 즉 우리가 바꾸고자 하는 정보를 기준으로 예를 들어보겠습니다.

Line 394 : [21:44:07 Oct 12 Fri] @0x3924004E|JVM| Free Memory: Heap [ 2368340/ 6291456], Native[ 7299824/32505856]

위와 같은 로그 정보는 다음과 같이 풀이됩니다.

  1. 라인넘버가 표시됩니다.L로 시작됩니다.
  2. 타임스탬프는 [ 대괄호로 시작됩니다.
  3. 3쌍의 숫자가 콜론(:)으로 구분되어 시간을 표시합니다.
  4. 날짜와 요일이 표시되고 ]로 대괄호가 닫힙니다.
  5. 제거되어야할 문자열들이 주르륵 이어지고
  6. Heap 이라는 단어 다음에
  7. [로 시작되며 남은 heap 메모리량과 슬래시(/)가 붙어 전체 heap 메모리량을 표시합니다.이 때 숫자의 길이에 따라 공백이 있을 수 있습니다.
  8. heap 메모리 정보는 ]로 끝나며 이후 native 메모리 정보가 같은 형식으로 표시됩니다

따라서 우리는 다음과 같은 정규식표현을 써서 필요한 정보를 패턴으로 묶어줍니다.

^L.+[(dd:dd:dd).+[([sd]+)/([sd]+)].+[([sd]+)/([sd]+)]$

그럼 괄호로 묶은 부분은 순서대로 (타임스탬프),(heap),(total heap),(native),(total native)가 되는 것이며 이는 순서대로 1,2,3,4,5가 됩니다. 이를 엑셀에서 쉽게 가져오기 위해서 임의의 구분자 |를 사용하겠습니다. 따라서 바꿀 단어는 \1|\2|\3|\4|\5가 되겠습니다.

찾을 단어와 바꿀 단어에 위에서 작성한 정규식을 넣어주고 정규표현식에 체크한 상태에서 ‘모두바꾸기’를 클릭하면 깔끔하게 필요한 정보만 남은 창을 보여줍니다. 이를 텍스트 파일로 저장한다음, 엑셀에서 불러들여 |로 구분하여 셀을 나눠주면 깔끔하게 그래프를 그릴 수 있습니다.

정규표현식의 활용

“정규표현식이 뭐야 그거 몰라 무서워”

라고 외면하던 시절이 있었지만 이렇게 강력한 기능이 있다는 사실을 깨닫고 완전 빠져들 수 밖에 없었습니다. 자바스크립트도 이러한 정규식을 지원하며 엑셀 VBA도 정규표현식 객체를 지원한다고 하더군요. 각종 데이터를 노가다로 가공해온 지난날에 대한 아련한 아픔이 느껴지는 순간입니다. 에디트 플러스나 울트라 에디터를 비롯하여 다른 거의 모든 편집기는 정규표현식을 지원하는 추세입니다. 막상 정규식 자체의 모양새는 암호 저리가라 할 만큼 이상해 보이기도 하지만 조금만 활용하면 엄청난 노가다를 너무나 손쉽게 처리해 버릴 수 있는 강력한 무기가 될 수도 있습니다. 아울러 adblock과 같은 광고 차단 익스텐션들도 정규식을 지원하는데요, 여기서는 정규식의 시작과 끝을 ‘/’ 슬래시로 감싸주면 광고필터를 정규식으로 인식합니다.즉

/.+shop.+naver.+$/

과 같이 입력한다면 shop, naver가 들어간 url의 소스는 모두 차단해버리게 되어 네이버 메인화면에서 약간 썰렁한 쇼핑몰 광고 이미지들을 한 방에 날려버릴 수 있게 되는 것이지요.