Subpatterns (서브 패턴)
서브 패턴은 둥근 괄호(()
)로 구분되며 중첩 될 수 있다. 패턴의 일부를 서브 패턴으로 표시하는 것은 다음 두 가지를 수행한다.
-
선택 집합을 지역화 한다. 예를 들어
cat(aract|erpillar|)
패턴은 "cat", "cataract" 또는 "caterpillar" 중 하나와 일치한다. 괄호가 없으면 "cataract", "erpillar" 또는 빈 문자열과 일치한다. -
서브 패턴을 캡처 서브 패턴으로 설정한다. 모든 패턴이 일치하면 서브 패턴과 일치하는 문자열의 부분은
pcre_exec()
의ovector
인수를 통해 호출자에게 다시 전달된다. 여는 괄호는 왼쪽에서 오른쪽으로 (1부터 시작) 카운트하여 캡처 서브 패턴의 수를 부여한다.
예를 들어 문자열 "the red king"이 ((red|white) (king|queen))
패턴과 일치하면 캡처된 부분 문자열이 "red king", "red" 및 "king"이며 아래와 같이 번호가 부여된다.
<?php
$string = 'the red king';
preg_match('/((red|white) (king|queen))/', $string, $matches);
print_r($matches);
//Array
//(
// [0] => red king
// [1] => red king
// [2] => red
// [3] => king
//)
평범한 괄호가 두 가지 기능을 수행한다는 사실이 항상 도움이 되는 것은 아니다. 캡처 요구 사항없이 그룹화 서브 패턴이 필요한 경우가 종종 있다. 여는 괄호 뒤에 "?:
"가 오는 경우 서브 패턴은 캡처를 수행하지 않으며 후속 캡처 서브 패턴의 수를 계산할 때는 계산되지 않는다.
예를 들어 문자열 "the white queen"이 ((?:red|white) (king|queen))
패턴과 일치하면 캡처 된 부분 문자열은 "white queen"과 "queen"이며 1과 2로 번호가 매겨진다. 캡처된 부분 문자열의 최대 수는 99이며 캡처 및 캡처하지 않는 모든 서브 패턴의 최대 수는 200개다.
<?php
$string = 'the white queen';
preg_match('/((?:red|white) (king|queen))/', $string, $matches);
print_r($matches);
//Array
//(
// [0] => white queen
// [1] => white queen
// [2] => queen
//)
캡처하지 않는 서브 패턴의 옵션이 필요한 경우 아래의 두 예시 처럼 "?" 그리고 ":" 사이에 옵션을 표기할 수 있다.
(?i:saturday|sunday)
(?:(?i)saturday|sunday)
정확히 동일한 문자열 세트와 일치해야 한다. 대체 분기는 왼쪽에서 오른쪽으로 시도되고 서브 패턴의 끝에 도달 할 때까지 옵션이 재설정 되지 않아 한 분기의 옵션 설정이 후속 분기에 영향을 미치므로 위 패턴은 "SUNDAY"및 "Saturday"와 일치한다.
<?php
preg_match('/(?i:saturday|sunday)/','Saturday', $matches);
print_r($matches);
// Array
// (
// [0] => Saturday
// )
preg_match('/(?:(?i)saturday|sunday)/','SUNDAY', $matches);
print_r($matches);
// Array
// (
// [0] => SUNDAY
// )
구문 (?P<name>pattern)
을 사용하여 서브 패턴의 이름을 지정할 수 있다. 그런 다음이 서브 패턴은 matches 배열에서 일반 숫자 위치와 이름을 기준으로 인덱싱 된다(PHP 5.2.2에서는 두 가지 대체 구문 (?<name>pattern)
과 (?'name'pattern)
을 사용할 수 있다).
<?php
$string = 'the white queen';
preg_match('/(?P<name>the)/', $string, $matches);
print_r($matches);
preg_match("/(?'name'the)/", $string, $matches);
print_r($matches);
//Array
//(
// [0] => the
// [name] => the
// [1] => the
//)
//Array
//(
// [0] => the
// [name] => the
// [1] => the
//)
때로는 일치하는 여러 개의 서브 그룹을 정규식에 포함시켜야 할 필요가 있다. 일반적으로 이들 중 하나만 일치할 가능성이 있더라도 각각의 고유한 역 참조 번호가 부여된다. 이 문제를 극복하기 위해 (?|
구문을 사용하면 중복되는 숫자를 가질 수 있다. 다음 정규식 (?:(Sat)ur|(Sun))day
을 "Sunday" 문자열과 비교해보자.
<?php
$string = 'Sunday';
preg_match('/(?:(Sat)ur|(Sun))day/', $string, $matches);
print_r($matches);
//Array
//(
// [0] => Sunday
// [1] =>
// [2] => Sun
//)
여기에서 "Sun"은 역 참조 2에 저장되고 역 참조 1은 비어 있다. 역 참조 1에서의 "Sat"는 역 참조 2에서 존재하지 않는다. (?|
를 사용하여 패턴을 변경하면 이 문제가 해결된다.
<?php
$string = 'Sunday';
preg_match('/(?|(Sat)ur|(Sun))day/', $string, $matches);
print_r($matches);
//Array
//(
// [0] => Sunday
// [1] => Sun
//)
이 패턴을 사용하면 Sun과 Sat가 모두 역 참조 1에 저장된다.
- PHP 정규식(PCRE)의 모든 것 - 프롤로그
- PHP 정규식(PCRE)의 모든 것 - 구분기호(Delimiters)
- PHP 정규식(PCRE)의 모든 것 - 메타문자(Meta-characters)
- PHP 정규식(PCRE)의 모든 것 - 이스케이프 시퀀스(Escape Sequences)
- PHP 정규식(PCRE)의 모든 것 - 유니코드 문자 속성(Unicode character properties)
- PHP 정규식(PCRE)의 모든 것 - 앵커(Anchors)
- PHP 정규식(PCRE)의 모든 것 - 마침표(Dot)
- PHP 정규식(PCRE)의 모든 것 - 캐릭터 클래스(Character classes)
- PHP 정규식(PCRE)의 모든 것 - 선택(Alternation)
- PHP 정규식(PCRE)의 모든 것 - 내부 옵션 설정(Internal option setting)
- > PHP 정규식(PCRE)의 모든 것 - 서브 패턴(Subpatterns)
- PHP 정규식(PCRE)의 모든 것 - 반복(Repetition)
- PHP 정규식(PCRE)의 모든 것 - 역 참조(Back references)
- PHP 정규식(PCRE)의 모든 것 - 어설션(Assertions)
- PHP 정규식(PCRE)의 모든 것 - 일회성 서브 패턴(Once-only subpatterns)
- PHP 정규식(PCRE)의 모든 것 - 조건부 서브 패턴(Conditional subpatterns)
- PHP 정규식(PCRE)의 모든 것 - 주석(Comments)
- PHP 정규식(PCRE)의 모든 것 - 재귀 패턴(Recursive patterns)
- PHP 정규식(PCRE)의 모든 것 - 에필로그