Use the lookahead expression (?!{{|}})to make sure you don't have a nested set of curly braces inside your outer set.
{{((?!{{|}}).)*}}
<?php
$string = '{{lot {{of}} characters}}';
for (;;)
{
var_dump($string);
$replacement = preg_replace('/{{((?!{{|}}).)*}}/', '', $string);
if ($string == $replacement)
break;
$string = $replacement;
}
string(25) "{{lot {{of}} characters}}"
string(19) "{{lot characters}}"
string(0) ""
, :
# Unbalanced braces.
string(23) "{{lot {{of}} characters"
string(17) "{{lot characters"
string(23) "lot {{of}} characters}}"
string(17) "lot characters}}"
# Multiple sets of braces.
string(25) "{{lot }}of{{ characters}}"
string(2) "of"
# Lone curlies.
string(41) "{{lot {{of {single curly} }} characters}}"
string(19) "{{lot characters}}"
string(0) ""