Reputation: 84
I am searching the whole day for a RegEx that matches just the inner {IF} - {ENDIF}-Statement in a nested condition code. Does anyone have an idea?
for example:
{IF bla}Text 1{ELSEIF ble}Text 2 {IF bli}Text 2.1{ELSE blo}Text 2.1{ENDIF} Main text end{/ENDIF}
I just want to get
{IF bli}Text 2.1{ELSE blo}Text 2.1{ENDIF}
i tried #\{IF .*\}.*\{ENDIF\}#is
but this is not working as i only get the whole string.
And also important: The code can have several lines and line breaks!
the bla, ble, bli etc are dynamic and can differ
Upvotes: 3
Views: 660
Reputation: 47991
This grabs your inner IF block:
/{IF(?:.*?(?={IF)(*SKIP)(*FAIL)|.*?){ENDIF}/
Demo (279 steps)
The pattern uses (*SKIP)(*FAIL)
and "disqualifies" any IF blocks that contain an inner IF block. This way you only get the innermost IF block.
Code: (Demo)
$string='{IF bla}Text 1{ELSEIF ble}Text 2 {IF bli}Text 2.1{ELSE blo}Text 2.1{ENDIF} Main text end{/ENDIF}';
echo preg_match('/{IF(?:.*?(?={IF)(*SKIP)(*FAIL)|.*?){ENDIF}/',$string,$match)?$match[0]:'fail';
Output:
{IF bli}Text 2.1{ELSE blo}Text 2.1{ENDIF}
Or faster/better with negative lookahead:
/{IF(?!.*{IF).*?{ENDIF}/
Demo (190 steps)
Upvotes: 0
Reputation: 887
Inner IF-ELSE:
{IF(?!.*{IF).*?}.*?{ENDIF}
(?!.*{IF)
looks ahead from that position and asserts it won't match?
are an instruction to stop at the earliest match.Upvotes: 1