정규식(PCRE) PCRE Patterns Recursive patterns
중첩된 괄호를 무제한으로 허용하는 괄호 안의 문자열을 일치시키는 문제를 고려하십시오. 재귀를 사용하지 않고 할 수 있는 최선은 중첩의 고정 깊이와 일치하는 패턴을 사용하는 것입니다. 임의의 중첩 깊이를 처리할 수 없습니다. Perl 5.6은 (무엇보다도) 정규 표현식이 재귀하도록 하는 실험적 기능을 제공했습니다. 특정 재귀의 경우에는 특수 항목(?R)이 제공됩니다. 이 PCRE 패턴은 괄호 문제를 해결합니다(PCRE_EXTENDED 옵션이 공백이 무시되도록 설정되었다고 가정): \( ( (?>[^()]+) | (?R) )* \)
먼저 여는 괄호와 일치합니다. 그런 다음 괄호가 아닌 시퀀스 또는 패턴 자체의 재귀 일치(즉, 올바르게 괄호로 묶인 부분 문자열)가 될 수 있는 임의의 수의 하위 문자열과 일치합니다. 마지막으로 닫는 괄호가 있습니다.
이 특정 예제 패턴에는 중첩된 무제한 반복이 포함되어 있으므로 일치하지 않는 문자열에 패턴을 적용할 때 괄호가 아닌 문자열을 일치시키기 위해 한 번만 사용하는 하위 패턴을 사용하는 것이 중요합니다. 예를 들어 (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
에 적용하면 "일치하지 않음"이 빨리 나옵니다. 그러나 한 번만 사용하는 하위 패턴을 사용하지 않으면 실제로 매우 다양한 방식으로 매치가 실행되기 때문에 매우 오랜 시간 동안 실행됩니다. * 반복은 주제를 세분화할 수 있으며 실패가 보고되기 전에 모두 테스트를 거쳐야 합니다.
캡처하는 하위 패턴에 대해 설정된 값은 하위 패턴 값이 설정되는 재귀의 가장 바깥쪽 수준의 값입니다. 위의 패턴이 (ab(cd)ef)
와 일치하는 경우 캡처 괄호의 값은 최상위 수준에서 취한 마지막 값인 "ef"입니다. 추가 괄호가 추가되면 \( ( ( (?>[^()]+) | (?R) )* ) \)
해당 문자열이 캡처하는 문자열은 "ab(cd)ef", 맨 위의 내용 수준 괄호. 패턴에 15개 이상의 캡처 괄호가 있는 경우 PCRE는 재귀 중에 데이터를 저장하기 위해 추가 메모리를 확보해야 합니다. 이는 pcre_malloc을 사용하여 수행하고 나중에 pcre_free를 통해 해제합니다. 메모리를 얻을 수 없는 경우 재귀 내에서 메모리 부족 오류를 제공할 방법이 없기 때문에 처음 15개의 캡처 괄호에 대한 데이터만 저장합니다.
(?1)
, (?2)
등은 재귀 하위 패턴에도 사용할 수 있습니다. 명명된 하위 패턴을 사용할 수도 있습니다: (?P>name)
또는 (?&name)
.
재귀적 서브패턴 참조 구문(숫자 또는 이름으로)이 참조하는 괄호 외부에서 사용되는 경우 프로그래밍 언어의 서브루틴처럼 작동합니다. 앞의 예에서는 (sens|respons)e and \1ibility
패턴이 "sense and sensibility" 및 "response and responsibility"과 일치하지만 "sense and 책임"은 일치하지 않는다고 지적했습니다. 대신 (sens|respons)e and (?1)ibility
패턴이 사용되는 경우 다른 두 문자열과 마찬가지로 "sense 및 responsibility"과 일치합니다. 그러나 그러한 참조는 참조하는 하위 패턴을 따라야 합니다.
주제 문자열의 최대 길이는 정수 변수가 보유할 수 있는 가장 큰 양수입니다. 그러나 PCRE는 재귀를 사용하여 하위 패턴과 무한 반복을 처리합니다. 이것은 사용 가능한 스택 공간이 특정 패턴으로 처리할 수 있는 주제 문자열의 크기를 제한할 수 있음을 의미합니다.