fork download
  1. use strict;
  2. use warnings;
  3.  
  4. my $re = qr~
  5. {if:\s*+
  6. (?<condition>
  7. [^{}]++
  8. )
  9. }
  10.  
  11. (?<then>
  12. (?:
  13. (?:(?!{if:[^{}]++}|{else}|{/endif}).)*+
  14. (?R)*+
  15. )*+
  16. )
  17.  
  18. (?:
  19. {else}
  20. (?<else>
  21. (?:
  22. (?:(?!{if:[^{}]++}|{else}|{/endif}).)*+
  23. (?R)*+
  24. )*+
  25. )
  26. )?+
  27.  
  28. {/endif}
  29. ~six;
  30.  
  31.  
  32. my $txt = <<'_STR_';
  33. {if: "'x' == 'y'"}
  34. a
  35. {else}
  36. b
  37. {/endif}
  38.  
  39. {if: "'x' == 'y'"}
  40. c
  41. {/endif}
  42.  
  43. {if:minimal}{else}{/endif}
  44.  
  45. {if: "'nested' == 'things'"}
  46. {if: "'x' == 'y'"}x{if:minimal}{else}{/endif}x{/endif}
  47. {else}
  48. b{if: "'x' == 'y'"}c{/endif}{if: "'x' == 'y'"}c{/endif}
  49. {/endif}
  50.  
  51. {if:foo} unbalanced {if:bar}ignores first if{/endif}
  52.  
  53. _STR_
  54.  
  55.  
  56. while($txt =~ /$re/g){
  57. print "*** matched if:\n";
  58. print " * cond: $+{condition}\n";
  59. print " * then: $+{then}\n";
  60. print " * else: $+{else}\n" if defined $+{else};
  61. }
  62.  
Success #stdin #stdout 0s 4724KB
stdin
Standard input is empty
stdout
*** matched if:
  * cond: "'x' == 'y'"
  * then: 
    a

  * else: 
    b

*** matched if:
  * cond: "'x' == 'y'"
  * then: 
    c

*** matched if:
  * cond: minimal
  * then: 
  * else: 
*** matched if:
  * cond: "'nested' == 'things'"
  * then: 
    {if: "'x' == 'y'"}x{if:minimal}{else}{/endif}x{/endif}

  * else: 
    b{if: "'x' == 'y'"}c{/endif}{if: "'x' == 'y'"}c{/endif}

*** matched if:
  * cond: bar
  * then: ignores first if