Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A few things:</p> <ol> <li><p>You were using <code>?</code> on your capturing groups which were containing <code>*</code>. The <code>*</code> means "0 or more times", so basically the contents are already optional. Using <code>?</code> doesn't do anything.</p> <pre><code>\{\{(?&lt;field&gt;[^&gt;]*)[ &gt; ]?(?&lt;looptemplate&gt;[^\}\}].*)\}\} </code></pre></li> <li><p><code>[ &gt; ]</code> matches <strong>1</strong> character. Either a space or <code>&gt;</code>. You probably meant <code>(?: &gt; )</code> (which matches <code>" &gt; "</code> (ignore the quotes, otherwise SO wouldn't render the spaces) and groups it together.</p> <pre><code>\{\{(?&lt;field&gt;[^&gt;]*)(?: &gt; )?(?&lt;looptemplate&gt;[^\}\}].*)\}\} </code></pre></li> <li><p><code>[^\}\}]</code> is the same as <code>[^\}]</code>. Negated character classes don't work with strings, they only work on every individual character inside, so writing one multiple times doesn't change anything. I guess that's why you tried the negative lookahead. This is right, but you need to check that condition for every single character of the repetition. Otherwise you only check once, that your <code>looptemplate</code> doesn't begin with <code>\}\}</code> but then you fire away with <code>.*</code>. So group <code>.</code> and the lookahead together:</p> <pre><code>\{\{(?&lt;field&gt;[^&gt;]*)(?: &gt; )?(?&lt;looptemplate&gt;(?:(?!\}\}).)*)\}\} </code></pre></li> <li><p>Your <code>(?: &gt; )</code> is optional, so if you have some <code>{{...}}</code> that doesn't contain it (only has the <code>field</code> part you will get the same problem as before, just this time with <code>[^&gt;]</code>. Include the lookahead here, too:</p> <pre><code>\{\{(?&lt;field&gt;(?:(?!\}})[^&gt;])*)(?: &gt; )?(?&lt;looptemplate&gt;(?:(?!\}\}).)*)\}\} </code></pre></li> </ol> <p>By the way, an alternative to using negated character classes or lookaheads is to use ungreedy repetition. If you can use negated character classes, that is usually preferable, because it's equally readable but usually more efficient than the ungreedy modifier, since it does not require backtracking. In your case you have to use the lookahead (because there is a pattern of two consecutive characters you don't want to go past, instead of just one character). In that case, the lookahead might cancel out the performance gains from avoiding backtracking, plus the lookahead is usually a bit less readable. So you might just want to go with an ungreedy repetition here (append the repetition quantifier with <code>?</code>):</p> <pre><code>\{\{(?&lt;field&gt;(?:(?!\}})[^&gt;])*)(?: &gt; )?(?&lt;looptemplate&gt;.*?)\}\} </code></pre> <p>Note that you cannot use an ungreedy repetition for <code>field</code> because, <code>(?: &gt; )</code> is optional. That would lead to <code>field</code> being empty and everything else (including a possible <code>" &gt; "</code> being matched by <code>looptemplate</code>. <strong>Unless</strong> you include the <code>&gt;</code> into an optional group together with <code>looptemplate</code>:</p> <pre><code>\{\{(?&lt;field&gt;[^&gt;]*?)(?: &gt; (?&lt;looptemplate&gt;.*?))?\}\} </code></pre> <p>One final note. This is only a matter of taste, but let me introduce you to a different form of escaping. Many meta-characters are no meta-characters when inside a character class (only <code>]</code>, <code>-</code>, <code>^</code> and <code>\</code> still are). So you can wrap your meta-character in a character class to escape it:</p> <pre><code>[{][{](?&lt;field&gt;[^&gt;]*?)(?: &gt; (?&lt;looptemplate&gt;.*?))?[}][}] </code></pre> <p>As I said, just a suggestion, but for most characters, I find this more readable than using a backslash.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload