profile

이 세상에 하나는 남기고 가자

세상에 필요한 소스코드 한줄 남기고 가자

PHP 정규식(PCRE)의 모든 것 - 캐릭터 클래스(Character classes)

유영재

Character classes (캐릭터 클래스)

캐릭터 클래스는 여는 대괄호([)와 닫는 대괄호(])로 영역을 선언한다. 닫는 대괄호는 그 자체만으로는 특별한 의미를 가지지 않는다. 닫는 대괄호가 클래스의 멤버로 필요하면 클래스의 첫 번째 데이터 문자(곡절 부호(^)로 시작하는 경우) 뒤에 있거나 백 슬래시로 이스케이프되어야 한다.

캐릭터 클래스는 문장의 단일 문자와 일치한다(단어가 아닌 단일 문자 단위로 일치한다).

캐릭터 클래스의 첫 번째 문자가 곡절 부호(^)가 아닌 경우 캐릭터 클래스에 정의된 문자 세트가 있으면 일치한다. 반대로 곡절 부호로 시작하는 경우 캐릭터 클래스에서 정의한 문자 세트가 없으면 일치한다. 곡절 부호(^)가 실제로 클래스의 구성원으로 필요하면 첫 번째 문자가 아닌지 확인하거나 백 슬래시로 이스케이프 처리해야 한다.

예를 들어, 캐릭터 클래스 [aeiou]는 소문자 모음과 일치하지만 [^aeiou]는 소문자 모음이 아닌 문자와 일치한다. 곡절 부호는 어설션이 아니며 클래스에 있는 문자를 열거하여 지정하는 편리한 표기법이다. 목표 문자열에서 문자를 찾아내며, 현재 위치가 문자열의 끝이면 실패한다.

대소문자를 구분하지 않으면(caseless) 클래스의 문자는 모든 대문자와 소문자를 나타낸다. 예를 들어 대소문자를 구분하지 않는 [aeiou]는 "A"와 "a"에 일치되나, 대소문자를 구분하지 않는 [^aeiou]는 구분하는 경우에 일치하는 "A"에는 일치하지 않는다.

<?php
$str = 'a';
echo ((preg_match('/[aeiou]/', $str)) ? 'matched' : 'not matched') . "\n";
//matched

echo ((preg_match('/[^aeiou]/', $str)) ? 'matched' : 'not matched') . "\n";
//not matched

echo ((preg_match('/[aeiou]/i', $str)) ? 'matched' : 'not matched') . "\n";
//matched

echo ((preg_match('/[^aeiou]/i', $str)) ? 'matched' : 'not matched') . "\n";
//not matched

$str = 'A';
echo ((preg_match('/[aeiou]/', $str)) ? 'matched' : 'not matched') . "\n";
//not matched

echo ((preg_match('/[^aeiou]/', $str)) ? 'matched' : 'not matched') . "\n";
//matched

echo ((preg_match('/[aeiou]/i', $str)) ? 'matched' : 'not matched') . "\n";
//matched

echo ((preg_match('/[^aeiou]/i', $str)) ? 'matched' : 'not matched') . "\n";
//not matched

개행 문자는 PCRE_DOTALL 또는 PCRE_MULTILINE 옵션의 설정에 관계없이 캐릭터 클래스에서 특별한 방법으로 처리되지 않는다. [^a]와 같은 캐릭터 클래스는 항상 개행 문자와 일치한다.

하이픈(-) 문자를 사용하여 캐릭터 클래스의 문자 범위를 지정할 수 있다. 예를 들어, [d-m]은 d와 m 사이의 모든 문자를 찾는다. 클래스에서 하이픈 문자가 필요하면 백 슬래시로 이스케이프하거나 범위를 나타내는 것으로 해석할 수 없는 위치(일반적으로 클래스의 시작 또는 마지막 문자)에 표시해야 한다.

리터럴 문자 "]"는 범위의 끝 문자로 사용할 수 없다. [W-]46]과 같은 패턴은 두 문자 ("W" 및 "-")의 리터럴 문자열 "46]"로 해석되므로 "W46]"또는 "-46"과 일치한다. 그러나 "]"이 역 슬래시로 이스케이프되면 범위 끝으로 해석되므로 [W-\]46]은 두 개의 개별 문자가 뒤에 오는 범위를 포함하는 단일 클래스로 해석된다. "]"의 8진수 또는 16진수 표현을 사용하여 범위를 끝낼 수도 있다.

범위는 ASCII 조합 순서로 정해진다. [\000-\037]와 같이 숫자로 지정된 문자를 사용할 수도 있다. 대소문자를 구분하지 않는(caseless) 일치가 설정 되었을 때는 범위 안의 문자들도 대소문자 구별없이 일치한다. 예를 들어 대소문자를 구분하지 않는 경우 [Wc][][\^_`wxyzabc]와 동일하며 "fr" locale 문자표를 사용하는 경우 [\xc8-\xcb]는 악센트 부호가 있는 E 문자와 일치한다. 두 경우 모두.

<?php
$str = '[][^_`xyzabc]';

preg_match('/[W-c]*/i', $str, $matches);
print_r($matches);
// Array
// (
//     [0] => [][^_`xyzabc]
// )

preg_match('/[\[\]\^_`xyzabc]*/i', $str, $matches);
print_r($matches);
// Array
// (
//     [0] => [][^_`xyzabc]
// )

문자 유형 \d, \D, \s, \S, \w\W는 캐릭터 클래스에도 사용할 수 있으며 일치하는 문자를 클래스에 추가한다. 예를 들어, [\dABCDEF]는 모든 16진수 형식과 일치한다. 곡절 부호는 대문자 문자 유형과 함께 사용하여 소문자 유형 보다 더 제한된 문자 집합을 편리하게 지정할 수 있다. 예를 들어 [^\W_] 캐릭터 클래스는 문자 또는 숫자와 일치하지만 밑줄은 사용할 수 없다.

\, -, ^(시작 부분) 및 종료 ]를 제외한 영숫자가 아닌 문자는 모두 캐릭터 클래스에서 특별한 의미를 가지지 않지만 이스케이프해도 문제가 되지 않는다. 패턴 종결자는 항상 특별하며 표현식 내에서 사용될 때는 이스케이프해야 한다.

Perl은 캐릭터 클래스에 대한 POSIX 표기법을 지원한다. 이것은 둘러싸는 대괄호 안에 [::]로 묶인 이름을 사용한다. PCRE는 또한 이 표기법을 지원한다. 예를 들어, [01[:alpha:]%]는 "0", "1", 모든 알파벳 문자 또는 "%"와 일치한다. 지원되는 클래스 이름은 다음과 같다.

Character classes

class 설명
alnum letters and digits
alpha letters
ascii character codes 0 - 127
blank space or tab only
cntrl control characters
digit decimal digits (same as \d)
graph printing characters, excluding space
lower lower case letters
print printing characters, including space
punct printing characters, excluding letters and digits
space white space (not quite the same as \s)
upper upper case letters
word "word" characters (same as \w)
xdigit hexadecimal digits

공백 문자는 HT(9), LF(10), VT(11), FF(12), CR(13) 및 공백(32)이다. 이 목록에는 VT 문자 (코드 11)가 포함되어 있다. 이렇게 하면 "space"가 \s와 다른데, 이는 VT (Perl 호환성)를 포함하지 않는다. word는 Perl extension이며 blank는 Perl 5.8의 GNU extension이다. 또 다른 Perl 확장은 콜론(:) 다음에 ^ 문자로 표시되는 부정이다. 예를 들어 [12[:^digit:]]는 "1", "2"또는 임의의 비 숫자와 일치한다.

UTF-8 모드에서 값이 128보다 큰 문자는 POSIX 캐릭터 클래스와 일치하지 않는다.


comments powered by Disqus