====== 정규 표현식 ====== Regular expression. **정규식**이라고도 부른다. "정규 표현식"이라는 말은 여러 의미로 쓰이지만 공통적으로 특정한 [[문자열]] [[집합]]을 표현하는 간결한 수단을 가리키며, 이름에서 알 수 있듯 본래는 이 집합이 [[정규문법]]으로 제한되었으나 지금은 별로 그런 제약은 없다. 문자열 처리에 널리 쓰이며 매우 유용하기 때문에 요즘의 거의 모든 [[프로그래밍언어]]는 정규식을 어떤 형태로든 지원하는 게 보통이다. 정규 표현식은 구현체에 따라 그 문법이나 기능에 있어 큰 차이가 있는데, 그 중에서 가장 큰 줄기는 다음과 같다. * [[POSIX]] 기본 정규 표현식(BRE) 및 확장 정규 표현식(ERE) * [[펄]] 정규 표현식 및 [[PCRE|펄 호환 정규 표현식]](PCRE) 두 줄기는 기본 철학이 매우 다른데, 전자는 성능을 위하여 표현력을 많이 희생했으며, 후자는 표현력을 극대화시키기 위해서 성능을 다소 희생한 면이 있다. 실제로 펄 정규식은 [[NP-난해]]하며(([[http://perl.plover.com/NPC/|Perl Regular Expression Matching is NP-Hard]]. 심심하면 펄 정규식으로 [[소수]]를 체크한다거나 [[문맥의존문법]]을 구현해 보시라.)) 모든 경우에서 최적으로 돌아가도록 구현하는 건 거의 불가능에 가깝다. (그래서 가장 많이 사용되는 경우에 대해서만 최적화하고 있다...) ===== 문법 ===== 거의 모든 정규 표현식들은 공통적으로 다음과 같은 문법을 포함한다. * ''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 이후로는 명령형으로 사용되는 ''(*...)'' 꼴의 문법도 사용한다.