user7213923
user7213923

Reputation: 84

PHP: RegEx for nested {IF} {ENDIF} Conditions

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

Answers (2)

mickmackusa
mickmackusa

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

linden2015
linden2015

Reputation: 887

Inner IF-ELSE:

{IF(?!.*{IF).*?}.*?{ENDIF}

  • (?!.*{IF) looks ahead from that position and asserts it won't match
  • The lazy quantifiers ? are an instruction to stop at the earliest match.

Demo

Upvotes: 1

Related Questions