Question

I have the following snippet where I would like to extract code between the {foreach} and {/foreach} using a regular expression:

{foreach (...)}
Some random HTML content <div class="">aklakdls</div> and some {$/r/template} markup inside.
{/foreach}

I already have:

{foreach [^}]*}

but I am unable to match anything after that. Is there any way to match anything BUT {/foreach} as a whole token? Please note that the content between {foreach}{/foreach} can also contain "{$" tokens.

Edit: BaileyP's & Tomalak's answers are correct, but I have chosen BaileyP's answer for simplicity sake.

Was it helpful?

Solution

I came up with this

/(?:{foreach .*?})(.*?)(?:{\/foreach})/gis

Tested with RegExr

OTHER TIPS

If your regex flavor did not support non-greedy matching, the following would do it, but since it does I recommend @BaileyP's answer.

\{foreach [^}]*\}((?:.(?!\{/foreach\}))*[^{]?)

Depending on your regex favour, negative zero-width look-ahead and non-capturing groups look a little different.

Here are the components:

\{foreach [^}]*\}  // pretty much self-explanatory
(                  // match group one starts (that's what you are looking for)
 (?:               // non-capturing group starts
  .                // anything...
  (?!\{/foreach\}) // ... that is not followed by "{/foreach}"
 )*                // non-capturing group ends, repeat as often as possible
 [^{]?             // match the last character, unless it is "{"
)                  // match group one ends, done
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top