정규식(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는 재귀를 사용하여 하위 패턴과 무한 반복을 처리합니다. 이것은 사용 가능한 스택 공간이 특정 패턴으로 처리할 수 있는 주제 문자열의 크기를 제한할 수 있음을 의미합니다.