정규 표현식의 기본

앞에서 잠깐 언급했지만 한대가리 한다는 사람들도 regex(앞으로 정규표현식 다 regex 라고 하겠습니다)를 접하면 "오 신이시여..." 를 연발하게 됩니다. 도대체가 예술이라고밖에 생각할 수 없는, 인간의 머리로 만들어냈다고 믿을 수 없는 경지의 기술이거든요. 그래서 그만큼 어렵기도 합니다.


regex를 다 안다
라고 하는 놈은 이 세상에 없습니다. 컴퓨터 전문 출판사 O'Reilly 에서 Mastering Regular Expressions를 출간한 저자라고 해도 regex 전문가라는 말은 해줄 수 있어도 regex의 모든 것을 다 아는 사람이라고 할 수는 없을 정돕니다. regex를 아는 대부분 컴쟁이들이 어울리지 않게 regex 쫌 할 줄 안다라고 겸손아닌 겸손을 떠는 것도 이때문입니다. 그도 그럴 것이 regex는 끝이 없습니다. 그래서 끝까지 배울 수가 없지요.

regex 실력은 이 도구를 활용하는 여러분 상상력에 달려 있거든요. 무슨소린지 배워보면 압니다. regex가 가장 빛을 발휘하는 환경은 Unix 프로그래밍이나 문서 작업에서입니다. regex 자체가 Unix 전문가들이 타자치는게 귀찮아서 조금씩 쌓기 시작한 내공이거든요. MS의 윈도우 환경에서도 조금씩 흉내를 내고 있기는 합니다만 Unix 의 기본 도구라는 점에서 ( 당연히 Linux에도 기본 도구입니다 ) 윈도우 사용자보다는 Unix 또는 Linux 사용자에게 친숙한 도구이기도 합니다.

하지만 윈도우 사용자 여러분도 regex의 맛을 느끼고 기본적인 부분을 일상생활속에서 활용할 수 있습니다. 대부분의 고급 편집기 (MS 워드 포함)에 이미 정규식이 정식 도구로 자리잡고 있거든요. 가장 기본에 충실하게 regex를 구현하고 있는 편집기로는 Ultra Editor가 있습니다. MS 워드에도 있긴 합니다만, MS가 언제나 그렇듯이 표준을 무시하고 제멋대로 만들어 놓아 거의 쓸모가 없습니다.  울트라 에디터는 쉐어웨어로 누구나 다운로드 받아 사용할 수 있습니다. [Ultra Editor 다운로드] 울트라 에디터에서 사용하는 regex 구문은 Unix 와 조금 다릅니다. Unix 호환이 되도록 설정을 바꿀 수 있지만, 이렇게 해도 조금 다르니 그냥 좀 다르다는 사실만 염두에 두세요.

일단 울트라 에디터에서 유닉스 정규식 호환이 되도록 설정을 바꿔줍니다. 고급 메뉴 설정 메뉴  찾기 탭 Unix 정규식 사용을 체크 이렇게 해줘야 Unix 랑 비슷해지고 또 그래야 여기 나온 예제 해볼 수 있습니다. 그대로 따라해도 안된다 싶으면, 이거 체크했는지 확인해 보세요. 또, 프로그래밍이 그렇듯이 정규식 또한 한치의 오차도 허용하지 않습니다. 단 한개의 오타라도 말도 안되는 결과가 나올 수 있습니다. 울트라 에디터에서 사용할 수 있는 regex는 전체 regex의 1/1000 정도밖에 되지 않습니다. 하지만, 이것만 가지고도 여러분은 regex로 마술을 부릴 수 있습니다

정규식 표현(Unix 구문)

  • \ 특수 기호의 시작을 나타냅니다. 영문으로는 원래 슬래쉬인데 한글 문서에서는 원화 표시로 나오는 그 문자 말입니다. 흔히 말하는 이스케이프 문자(escape character)를 뜻합니다. 예를 들어, n은 n이라는 문자를 말하지만 \n 이란건 개행문자(newline)를 뜻합니다. 여러분이 키보드로 쳐넣을 수 없는 특수문자를 말하는 겁니다. 왜 escape문자라고 하느냐... 원래의 의미에서 탈출해 다른 의미를 갖게 해주기 때문입니다. '\' 이 문자 자체의 문자적 의미를 되살리려면 두번 붙여 써 주면 됩니다. \\ 이렇게...
  • ^ 줄의 시작 문자와 일치합니다. 줄의 시작문자라는 것 역시 눈에 보이거나 키보드로 쳐넣을 수 있는게 아닙니다.
  • $ 줄의 끝 문자와 일치합니다. 역시 마찬가지구요.
  • * 앞에 어떤 문자가 있건 그 문자가 0번 혹은 그 이상 반복되는 걸 말합니다.

예를 들어, a* 라면 a가 안나오는 경우 (a 0번 반복), a (1번), aa (2번)...

  • + 앞에 어떤 문자가 있건 그 문자와 하나 또는 여러 개와 일치합니다. 적어도 하나의 문자가 발견됩니다.

예를 들어, a+ 라면 a가 안나오는 경우는 포함되지 않고 최소한 a가 1번은 있어야 합니다.

  • . 개행 문자 이외의 어떤 문자라도 일치합니다. a. 라고 하면 a로 시작해서 어떤 문자든 문자 하나가 따라온다는 뜻입니다. ab, ac, ad 식의 ... a 는 a뒤에 아무것도 없기 때문에 일치하지 않습니다.
  • [] 괄호 안에 열거한 문자 중 어떤 것이라도...의 뜻입니다. '[abc]D' 라고 하면 aD, bD, cD 식의 문자가 일치합니다. 순서가 있는 문자 조합인 경우, 예를 들어, [a-z] 라고 하면 알파벳 전부, [0-9] 라고 하면 숫자 전부를 말합니다. 대소문자 일치 기능을 쓰지 않으면 '[a-zA-Z]'라고 해야 알파벳 대소문자 전부를 뜻합니다. 부정할 수도 있습니다. [^a-z] 라고 하면 알파벳을 제외한 모든 문자가 됩니다.

이스케이프 문자 얘기했지요? [a-zA-Z0-9] 라고 하면 특수문자를 제외한 모든 문자라는 뜻이 됩니다. 매번 이렇게 쓰는 거 귀찮아서 유닉스 컴쟁이들은 이스케이프 문자를 활용해 이런 것도 만들었습니다.

  • \d 숫자와 일치. [0-9] 과 같습니다. 여기서 d는 digit을 말합니다.
  • \D 숫자가 아닌 문자. [^0-9] 와 같습니다.
  • \w 단어 문자와 일치. [a-zA-Z0-9]
  • \W 단어가 아닌 문자와 일치. 여기서 w는 whitespace를 말하는데요. whitespace란 공백문자를 뜻합니다. 단순히 스페이스바로 넣는 공백문자뿐 아니라 탭이나 기타 formatting의 의미를 갖는 공백, 탭, 개행문자 등등을 모두 포함합니다.
  • \n LF 문자. linefeed를 뜻합니다. 개행문자로 Unix 에서는 이것만 씁니다.
  • \r CR 문자. carriage return을 뜻합니다. 윈도우에서는 \r\n 두개를 개행문자로 씁니다.

\r 과 \n 은 실제 타자기에서 나온 겁니다. \n은 타자기에서 다음줄로 넘어가는 걸, \r은 손으로 밀어서 타자 위치를 잡는 걸 말하거든요. 컴퓨터 편집기는 이걸 알아서 하거나 여러분도 return이란 걸 치지요? Enter 키가 옛날엔 Return 키였습니다. 지금도 return이란 말 쓰기도 하구요.

  • \s 공백, 탭. 개행문자, 즉 새로운 줄과는 일치하지 않습니다. \w보다 작은 뜻.
  • \S 공백이 아닌 문자와 일치. 역시 개행 문자, 즉 새로운 줄과는 일치하지 않습니다. \W보다 작은 뜻.
  • \t 탭 문자. 탭문자 역시 눈에 보이지 않지요. 긴 문서에서 탭문자 없애느라고 손으로 하루 종일 뺑이치는 분을 본 적도 있습니다. \t 를 공백으로 찾고 바꾸기 하면 1초면 끝날 일을...

참고로 특수문자 얘기가 나왔는데, 한글은 정확하게 잡지 못할 수도 있습니다. 영문의 입장에서 보면 (regex도 알파벳을 기준을 하기 때문) 한글은 모두 특수문자에 들어갑니다. escape 문자를 사용할땐 주의하세요.

  • () 오 신이시여.... 가 드디어 나옵니다. regex의 진수는 찾기에 있지 않습니다. 바로 바꾸기에 있습니다. 앞에서 찾은 내용을 가공해서 바꾸기에 활용한다는 뜻입니다. regex가 아니라면 절대 할 수 없는 일입니다.

괄호 '()' 를 쓰는 예를 들어볼게요. Wankyu Choi <wankyuchoi@gmail.net> 식의 이메일 표기를 1000페이지 문서에서 찾아서 HTML 메일 태그로 변환하고 싶다... 이거 손으로 하려면 얼마나 오랜 시간이 걸릴까요? 잠시 고민...

다시 말해 다음과 같은 메일 태그로 바꿔주는 겁니다:

<a href="mailto:wankyuchoi@gmail.com">Wankyu Choi</a>

이런건... regex 아니면 진짜 맨땅에 헤딩을 넘어 새끼 손가락으로 물구나무 서기나 다름 없습니다. regex를 쓰면:

* 찾기 표현: (이메일 주소앞에 나오는 이름을 찾는 regex)@(이메일 주소를 찾는 regex)

* 바꾸기 표현: <a href="mailto:\2">\1</a>

라고 해주면 된다는 겁니다. ' \ ' 문자를 사용했으니 \11 과 다르다는 건 알겠지요? 바로 앞에 나온 첫번째 괄호 부분 찾기의 결과값을 뜻합니다. \2 는 두번째 괄호... 1000페이지.... 이걸 손으로 하겠다는 사람이 있다면 1주일은 넘게 걸릴 겁니다.

앞에서도 말했지만 regex의 한계는 여러분 상상력의 한계와 일치합니다. regex를 art라고 하는 이유가 여기 있어요. 쓰는 사람의 손에서 예술적 가치가 나옵니다 :-)

3부로 넘어갑니다.

+ Recent posts