POSIX 확장(POSIX ERE, POSIX Extended Regular Expressions)
BSD 표준
GNU 기본(GNU BRE)
GNU 확장(GNU ERE)
펄 호환(PCRE)
이중 POSIX 기본 및 확장 정규 표현식은 솔라리스의 각종 유틸리티에서 사용한다. BSD표준도 솔라리스에서 사용되었지만, 지금은 사용되지 않는다. GNU BinUtils에 사용되는 정규표현식은 GNU 기본을 사용하는 유틸리티(grep, sed)와 GNU 확장을 사용할 수 있는 유틸리티(egrep, awk)로 구분되어있다. 마지막으로 펄 호환 정규 표현식은 펄 프로그래밍 언어에서 사용하는 정규표현식을 사용할 수 있다. 이외에도 각종 어플리케이션에서는 각 어플에 맞는 고유한 정규표현식을 가지고 있는 경우가 많다.
정규표현식을 사용하는 유틸리티중 유명한것을 꼽으라면 grep 이 아닐까 한다. 원칙적으로 grep 에 사용되는 식은 제한적인 정규표현식이긴 하지만, 매우 유용하게 사용할 수 있을 것이다. 아래에 몇가지 대표적인 예제를 보였다.
[] 안에 기술된 문자는 각 문자의 매칭을 의미한다.
예) [abc] - a, b, c 중 하나의 문자에 매칭
[ 뒤에 오는 ^ 은 not 의 의미다.
예) [^abc] - a, b, c 가 아닌 문자에 매칭
., *, [, \ 문자는 []안에서 특수문자로 취급하지 않는다.
[., .]: 콜레이션(Collation, 정렬이나 검색을 위해 문자를 비교할 때 사용하는 규칙)에서 특별한 심볼을 지정. 한국어에서는 해당 없다.
예) [.ch.] - ch 심볼을 의미.
[=, =]: 콜레이션(Collation)에서 특별한 심볼을 지정. 한국어에서는 해당 없다.
예) [=a=] - aa`a^ 심볼을 의미
[:alnum:], [:cntrl:], [:lower:], [:space:], [:alpha:], [:digit:], [:print:], [:upper:], [:blank:], [:graph:], [:punct:], [:xdigit:], [:name:] 1): 각 콜레이션에 맞는 캐릭터를 의미한다. alnum(영문숫자), cntrl(제어문자), lower(소문자), space(공백문자), alpha(알파벳), digit(숫자), print(출력가능문자), upper(대문자), blank(빈문자(공백문자 및 탭)), graph(출력가능하고볼수있는문자), punct(문장부호(.,;:)), xdigit(16진수숫자), name(LC_CTYPE 에 정의된 문자)
- 은 범위를 지정한다. 예를 들어 [a-z] 은 a ~ z 문자를 의미한다. [ac-] 은 a, c, - 문자를 의미한다. [0-9] 은 0 ~ 9 까지의 문자를 의미한다.
1) 솔라리스 기본 정규표현식에서는 콜레이션 관련 브래킷([..], [==], [::])을 지원하지 않는경우가 있다. 따라서 솔라리스의 일부 번들 프로그램에서는 [::]을 이용한 정규표현식을 사용할 수 없다.
사용예) [0-9[:space:][=a=]def.\]
다중 문자 매칭
\(\): 각 부 표현식을 그룹으로 묶어줄때 사용한다. 예) \(a[bc]\)\([bc]a\) - a 다음에 b또는 c가 와야하고, 다시 b또는 c가 온 후 a가 온 경우, 첫 두 글자를 1번 그룹, 다음 두 글자를 2번그룹으로 나눈다.
\n: 백 레퍼런스 표현식. n은 1~9까지의 숫자. 그룹에 매치된 값을 표현한다. 매치될 값이 없다면 매치 실패로 간주한다. 예) \(a[bc]*\)\1 - a 다음에 b 또는 c가 와야하고 이 규칙을 한번 더 적용한다. 즉 ab 는 매칭되지 않고 abac 는 매칭된다.
\{m\}, \{m,n\}, \{m,\}, \{,n\}: \{m\}은 m 회 매칭을 의미하고, \{m,n\}은 m회~n회 매칭됨을 나타낸다. \{m,\}은 m회 이상, \{,n\}은 n회 이하 매칭되는 것을 의미한다.
*: 괄호 밖에서 사용될 경우 앞의 문자에 매치되지 않거나 하나 이상 매치됨을 나타낸다. {0,}와 동일한 의미다. 예) [ab]* - [], [ab], [ab][ab], [ab][ab][ab] ...에 매치되는 것을 의미한다.
주의) \n에 매치된 표현식이 두개 이상 있는 경우 마지막 매칭된 심볼들을 따라간다. 예를 들어 ^\(ab*\)*\1$ 는 ababbabb 와 매치되지만, ababbab에는 매치되지 않는다. ([0-9])\1+의 경우 222는 매치되지만 234는 매치되지 않는다.
앵커
^: 정규표현식의 시작을 의미
$: 정규표현식의 끝을 의미
사용예) 정규표현식 ^abc$ 은 abc 는 매칭되지만 abcd 는 매칭하지 못한다.
우선순위
[==] [::] [..]
\<특수문자>
[]
\(\) \n
* \{m,n\}
나머지
^ $
쉽게 말해 콜레이션 관련 특수문자가 먼저 해석되고 다중 문자에 이어 ^ 와 $ 가 가장 마지막에 해석된다.
POSIX ERE
POSIX BRE에 비해 아래와 같이 추가되거나 삭제되어있다.
다중 문자 매칭
다중 문자 매칭임을 표시하기 위한 \ 은 사용하지 않아도 된다. 즉 \{1\} 이 아니라 {1} 을 사용할 수 있다.
+ 가 추가되었다. {1,}와 동일한 의미다
? 가 추가되었다. {,1}와 동일한 의미다
| 이 추가되었다. 두개의 표현식 중 하나에 해당되면 매칭. 예를 들어 정규표현식 a((bc)|d) 의 경우 abc 또는 ad 에 매칭한다. 단 abcd 는 매칭하지 않는다.
백 레퍼런싱(\n)은 삭제
\ 은 사용하지 않아도 된다. \( \) → ( ), \{ \} → { }
우선순위
[==] [::] [..]
\<특수문자>
[]
()
* {m,n}
나머지
^ $
|
우선순위는 POSIX BRE와 별로 다르지 않다. | 이 마지막에 해석되는 것에 주의하자.
GNU BRE/ERE
GNU BRE는 GNU grep 에서 사용하는 문법이다. POSIX BRE에서 아래와 같이 확장되었다.
** 를 허용. * 와 같은 의미.
\+, \?, \| 사용 가능. 의미는 POSIX ERE 의 +, ?, | 와 동일
GNU ERE는 GNU egrep 에서 사용하는 문법이다. POSIX ERE에서 아래와 같이 확장되었다. [grep -E]에서도 사용된다.
이 라이브러리는 NetBSD Editline 라이브러리의 autotools, libtoolize 가능한 판이다. (다른 시스템에서도 사용할 수 있도록 포팅되었다는 의미다) GNU Readline 라이브러리와 동일한 기능을 하고 같은 메소드를 제공해준다. GNU Readline 은 GPL 라이선스(LGPL라이선스가 아니다!), libedit 는 BSD스타일의 라이선스를 가지고 있다.
솔라리스 11에는 번들되어있다.
# wget http://thrysoee.dk/editline/libedit-20210714-3.1.tar.gz
# tar xvfz libedit-20210714-3.1.tar.gz
# cd libedit-20210714-3.1
# ./configure CFLAGS="-m64"
# vi src/vis.c 2)
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
# make 1)
# sudo make install
1) GNUAwk 4.x 가 필요하다. 2) Linux 에는 /usr/include/sys/param.h에 MIN, MAX 매크로가 있지만 솔라리스에는 없다. 매크로를 추가해준다.
root@ ~ # pcretest -d -t
PCRE version 8.34 2013-12-15
re> /(a|bc)x+yz/
Compile time 0.0032 milliseconds
------------------------------------------------------------------
0 26 Bra
3 7 CBra 1
8 a
10 7 Alt
13 bc
17 14 Ket
20 x++
22 yz
26 26 Ket
29 End
------------------------------------------------------------------
Capturing subpattern count = 1
No options
No first char
Need char = 'z'
data> abyz
Execute time 0.0017 milliseconds
No match
data> axyz
Execute time 0.0007 milliseconds
0: axyz
1: a
data>
예를 들자면, !#$%&*+-/=?^_`{}|~@[192.168.0.100]도 올바른 메일 주소다. 하지만 현실적으로 아래와 같은 정규표현식만으로도 대부분의 이메일 주소는 매칭할 수 있을 것이다. 아래 식은 HTML 5에서 input 태그의 type="email" 에 사용되는 정규표현식이다. (4.10.7.1 States of the type attribute - E-Mail STATE에서 발췌)
IPv4는 0.0.0.0 ~ 255.255.255.255 까지의 주소다. 아래는 999.999.999.999 까지 매칭되지만, IP 적합성 여부는 소프트웨어적으로 하는 것이 좋다는게 내 생각이다. (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)형식의 정규표현식을 사용할 필요는 없다는게 내 생각이다.