가능합니다!
$data = <<<LOD
{{START1}}
aaaaa
{{START2}}
bbbbb
{{START3}}
ccccc
{{START4}}
ddddd
{{END4}}
{{END3}}
{{END2}}
{{END1}}
LOD;
$pattern = '~(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))~';
preg_match_all ($pattern, $data, $matches);
print_r($matches);
설명 :
부분 : 패턴의이 부분은 {{START#}}
와 중첩 된 구조를 설명
({{START\d+}}(?>[^{]++|(?1))*{{END\d+}})
및 {{END#}}
( # open the first capturing group
{{START\d+}}
(?> # open an atomic group (= backtracks forbidden)
[^{]++ # all that is not a { one or more times (possessive)
| # OR
(?1) # refer to the first capturing group itself
) # close the atomic group
{END\d+}} #
) # close the first capturing group
당신은 재귀 정규 표현식을 사용하여 콘텐츠의 각 레벨을 가질 수있다
이제는이 부분으로 만 모든 레벨을 캡처 할 수 없다는 것이 문제입니다. 문자열의 모든 문자는 패턴에 의해 소비됩니다. 즉, 문자열의 겹쳐진 부분을 일치시킬 수 없습니다.
이
(?=({{START\d+}}(?>[^{]++|(?1))*{{END\d+}}))
이 모든 레벨과 일치합니다 :
문제는 그 결과, 룩어 (?=...)
같은 문자를 소비하지 않는 제로 폭 주장 내부의 모든 부분을 래핑하는 것입니다.
Perl과 같은 언어로 번역 할 수있는 트릭이 내 켄을 넘어서는 있지만 정규식의 대부분의 맛은 사용할 수 없습니다. 펌핑 보조 정리에 대해 읽어보고 왜 할 수 없는지 알아보십시오. – siride
귀하의 서식을 입력이라고 가정합니다. 좀 더 설명했다면 아마 다른 대안이 제시 될 수 있습니다. –
당신이 뭔가를 구문 분석하려고하는 것처럼 들리 네요. [뭔가가 HTML처럼 복잡해지면 (저에게 그렇게 보입니다), 정규식으로 처리하는 것은 나쁜 생각입니다.] (http://stackoverflow.com)/question/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454 # 1732454) – michaelb958