정규 표현식

Regular expression. 정규식이라고도 부른다. "정규 표현식"이라는 말은 여러 의미로 쓰이지만 공통적으로 특정한 문자열 집합을 표현하는 간결한 수단을 가리키며, 이름에서 알 수 있듯 본래는 이 집합이 정규문법으로 제한되었으나 지금은 별로 그런 제약은 없다. 문자열 처리에 널리 쓰이며 매우 유용하기 때문에 요즘의 거의 모든 프로그래밍 언어는 정규식을 어떤 형태로든 지원하는 게 보통이다.

정규 표현식은 구현체에 따라 그 문법이나 기능에 있어 큰 차이가 있는데, 그 중에서 가장 큰 줄기는 다음과 같다.

두 줄기는 기본 철학이 매우 다른데, 전자는 성능을 위하여 표현력을 많이 희생했으며, 후자는 표현력을 극대화시키기 위해서 성능을 다소 희생한 면이 있다. 실제로 펄 정규식은 NP-난해하며1) 모든 경우에서 최적으로 돌아가도록 구현하는 건 거의 불가능에 가깝다. (그래서 가장 많이 사용되는 경우에 대해서만 최적화하고 있다…)

문법

거의 모든 정규 표현식들은 공통적으로 다음과 같은 문법을 포함한다.

  • a와 같이 특수한 문자(메타문자)가 아닌 보통 문자는 정확히 그 문자를 가리킨다. 다만 설정에 따라(예를 들어서 i 변경자) 대소문자 구분을 안 할 수 있다.
  • ab와 같이 두 개의 패턴이 붙은 것은 보통 첫번째 패턴에 해당하는 문자열과 두번째 패턴에 해당하는 문자열을 이어 놓은 문자열을 의미한다.
  • 앞에 있는 패턴의 의미를 변경시키는 메타문자들은 보통 한 문자(및 그 뒤에 붙은 메타문자들)의 의미만을 바꾼다. 괄호를 사용하여 여러 문자를 한 패턴으로 처리하도록 할 수 있다. 또한 많은 정규 표현식 구현에서 괄호는 그 괄호 안에 대응되는 문자열을 별도로 기억하도록 할 것을 명령하는 역할을 하기도 한다(capturing).
  • *는 보통 앞에 붙은 패턴을 0번 또는 그 이상 반복한 문자열을 가리킨다. 이를테면 a*는 빈 문자열을 포함해 a만으로 이루어진 문자열을 가리킨다. 그 밖에도 +(한 번 이상), ?(0번 또는 1번), {m,n}(m번 이상 n번 이하) 등등을 지원하는 경우가 많다.
  • 여러 패턴이 |로 구분되어 있는 패턴은 안에 있는 패턴이 가리키는 문자열들의 합집합을 의미한다. 이를테면 a*|b*는 a로만 이루어져 있거나 b로만 이루어진(섞일 수는 없다) 문자열들을 의미하고, (a|b)*는 a나 b로만 이루어져 있는(섞일 수 있다) 문자열들을 의미한다.
  • ^, $는 특정한 문자를 가리키지는 않지만 이 위치에 문자열, 또는 설정에 따라서는 한 줄의 시작 및 끝이 와야 함을 가리킨다. 이런 식으로 특정 문자열을 가리키지 않는 메타문자들을 "너비가 없는"(zero-width) 패턴이라 부른다.

펄 호환 정규 표현식에서는 () 괄호 문법의 맨 첫 문자로 대부분의 메타 문자가 올 수 없음을 악용(?)하여, (?…) 꼴의 문법을 특수한 목적(조건 체크, 임의의 코드 삽입, 설정 변경 등등)으로 사용한다. 펄 5.10 이후로는 명령형으로 사용되는 (*…) 꼴의 문법도 사용한다.

1) Perl Regular Expression Matching is NP-Hard. 심심하면 펄 정규식으로 소수를 체크한다거나 문맥의존문법을 구현해 보시라.

도쿠위키DokuWiki-custom(rev 9085d92e02)을 씁니다.
마지막 수정 2011-05-30 18:25 | 외부 편집기