2012-05-19 3 views
0

이 질문은 PCRE와 관련이 있습니다.패턴이있는 재귀 PCRE 검색

는 이런 구조에서 사용 중첩 괄호위한 반복 검색을 보이면서 :

\(((?>[^()]+)|(?R))*\) 

이 가진 문제는, 그 '는 [^()] +'는 개행을 포함하는 임의의 문자와 일치 할 때 괄호, 괄호, 문장 부호, 단일 문자 등과 같은 한 문자 만 일치시켜야합니다.

'('및 ')'문자를 패턴 (예 : 'BEGIN'및 'END'와 같은 키워드).

나는 다음과 같은 구조로 올라와있다 :

BEGIN <<date>> 
    <<something> 
    BEGIN 
     <<something>> 
    END <<comment>> 
    BEGIN <<time>> 
     <<more somethings>> 
     BEGIN(cause we can)END 
     BEGINEND 
    END 
    <<something else>> 
END 

이 성공적으로 중첩 된 BEGIN..END 쌍을 일치합니다

(?xs) (?# <-- 'xs' ignore whitespace in the search term, and allows '.' 
       to match newline) 
(?P<pattern1>BEGIN) 
(
    (?> (?# <-- "once only" search) 
     (
     (?! (?P=pattern1) | (?P<pattern2>END)). 
    )+ 
    ) 
    | (?R) 
)* 
END 

이 실제로 다음과 같습니다 뭔가 작동합니다.

나는라는 이름의 패턴 patter1을에 대한 하는 pattern2 각각END을 BEGIN을 설정합니다. 검색어에 패턴 1을 사용하면 문제가 없습니다. 그러나 검색 끝에는 패턴 2을 사용할 수 없습니다. 'END'을 작성해야합니다.

어떻게하면이 패턴을 한 번만 지정하고 코드 내에서 "사방"에만 사용할 수 있도록이 정규식을 다시 작성할 수 있습니까? 즉, 검색 중간과 끝에 매우 END을 쓸 필요가 없습니다.

+0

안녕하세요. 내 대답이 전혀 도움이 되었습니까? 그렇지 않다면 어떻게 설명 할 수 있습니까? – Kobi

+0

@Kobi : 예제 (http://regex101.com/r/aG7wP4)를 보면 패턴 중 하나가 일치하지 않는 한 가장 바깥 쪽 블록과 만 일치합니다 (BEGIN 또는 END 키워드 중 하나의 철자가 잘못되었거나 생략되었습니다)). – OnlineCop

답변

3

는, 다음과 같은 정규 표현식을 참조하십시오 : 가장 맛에 패턴의 시작에 내다을 사용하는 것입니다

(?xs) 
(?(DEFINE) 
     (?<pattern1>BEGIN) 
     (?<pattern2>END) 
) 
(?=((?&pattern1) 
(?: 
    (?> (?# <-- "once only" search) 
     (?: 
     (?! (?&pattern1) | (?&pattern2)) . 
    )+ 
    )* 
    | (?3) 
)* 
(?&pattern2) 
)) 

이 정규식은 당신도 가져올 수 있습니다 각 개별 데이터 블록에 대한 데이터! 첫 번째 두 개가 define 블록에 정의되었으므로 세 번째 역 참조를 사용합니다.

데모 : http://regex101.com/r/bX8mB6

0

이러한 구조를 생성하는 데 사용되는 (?(DEFINE)) 블록의 경우에는 좋은 것으로 보입니다. 펄 예는 다음과 같습니다

(?xs) 
(?(DEFINE) 
     (?<pattern1>BEGIN) 
     (?<pattern2>END) 
) 
(?&pattern1) 
(
    (?> (?# <-- "once only" search) 
     (
     (?! (?&pattern1) | (?&pattern2)). 
    )+ 
    ) 
    | (?R) 
)* 
(?&pattern2) 

예 : http://ideone.com/8o9cg

(난 정말 어떤 펄을 알고하지 마십시오, 그것은 온라인 테스터의에 PHP에서 작동하도록 얻을 수 없었다하시기 바랍니다)

은 참조 : http://www.pcre.org/pcre.txt


작동하는 낮은 기술 솔루션을 (그들이 페이지가있는 것처럼 보이지 않는 (?(DEFINE) 0 확인) 더 @Kobis 답변을 확장 할 수

(?=.*?(?P<pattern1>BEGIN)) 
(?=.*?(?P<pattern2>END)) 
... 
(?P=pattern1) (?# should work - it was captured)