我想匹配smarty模板中的if else语句。并插入我自己的标签。在我的示例中<OPEN>
和</CLOSE>
。
这是我的代码:
$value =
<<<SMARTY
{if}
text1
{if}
text2
{/if}
text3
{/if}
{if}
text1
{else}
text2
{/if}
{if}
text1
{if}
text2
{else}
text3
{/if}
text
{/if}
SMARTY;
echo filter($value);
function filter($value)
{
$pattern =
'(\{(?:if|else).*?\})'. // open
'((?:'.
'[^{]'.
'|\{(?!/?if|else)'.
'|(?R)'.
')+)'.
'(\{(?:\/if|else)\})'; // close
return preg_replace_callback('#'.$pattern.'#', 'filter_callback', $value);
}
function filter_callback($matches)
{
$m2 = $matches;
$m2[0] = preg_replace(array('/[\n\r]/','/ +/','/^ /'),array('',' ',''), $m2[0]);
$m2[2] = preg_replace(array('/[\n\r]/','/ +/','/^ /'),array('',' ',''), $m2[2]);
print_r($m2);
return $matches[1].'<OPEN>'.filter($matches[2]).'</CLOSE>'.$matches[3];
}
但它正常工作。
例如,我希望得到以下输出:
{if}<OPEN>
text1
</CLOSE>{else}<OPEN>
text2
</CLOSE>{/if}
和
{if}<OPEN>
text1
{if}<OPEN>
text2
</CLOSE>{else}<OPEN>
text3
</CLOSE>{/if}
text
</CLOSE>{/if}
如果有人有想法?
答案 0 :(得分:1)
此任务不需要递归正则表达式。 PHP中的递归正则表达式的问题在于,您无法轻松访问不同递归级别的捕获。对于替换任务,你可以忘记它。
另一种解决方案:
$searches = array('{if}', '{else}', '{/if}');
$reps = array('{if}<OPEN>', '</CLOSE>{else}<OPEN>', '</CLOSE>{/if}');
$result = str_replace($searches, $reps, $value); // probably the faster way
或
$patterns = array('~{if}~', '~{else}~', '~{/if}~');
$reps = array('$0<OPEN>', '</CLOSE>$0<OPEN>', '</CLOSE>$0');
$result = preg_replace($patterns, $reps, $value);
print_r($result);
注意:您可以使用以下方法避免一次传递:
$patterns = array('~(?<={if}|{else})~', '~(?={(?:/if|else)})~');
$reps = array('<OPEN>', '<CLOSE>');
编辑:如果你想提取params并将它们作为一种标签属性重用,你可以使用preg_replace方式(不需要使用preg_replace_callback)来实现:
$patterns = array('~{if(?:( )[^(}]+\(([^)]+)\))?}~', '~{else}~', '~{/if}~');
$reps = array('$0<OPEN$1$2>', '<CLOSE>$0<OPEN>', '<CLOSE>$0');
$result = preg_replace($patterns, $reps, $value);
注意:描述参数的子模式[^)]+
可以替换为(?s)(?>[^)\']++|\'(?>[^\'\\]++|\\{2}|\\.)*\')+
,以允许用单引号括起参数内部的括号。
答案 1 :(得分:0)
以下是匹配特殊if语句的具体示例:
$value =
<<<SMARTY
{if}
text1
{if \$user->isAllowed(null,'favourites','read')}
text2
{/if}
text3
{/if}
{if \$user->isAllowed(null,'favourites','read')}
text1
{else}
text2
{/if}
{if \$user->isAllowed(null,'favourites','read')}
text1
{if}
text2
{else}
text3
{/if}
text
{/if}
SMARTY;
echo filter($value);
function filter($value)
{
$pattern =
'(\{(?:if|else).*?\})'. // open
'((?:'.
'[^{]'.
'|\{(?!/?if|else)'.
'|(?R)'.
')+)'.
'(\{(?:\/if|else)\})'; // close
return preg_replace_callback('#'.$pattern.'#', 'filter_callback', $value);
}
function filter_callback($matches)
{
if(preg_match('#\{if.*?\$user\-\>isAllowed\((.*?)\)[^\}]*?\}#', $matches[1], $params)) {
return $matches[1].'<OPEN '.$params[1].'>'.filter($matches[2]).'</CLOSE>'.$matches[3];
}
return $matches[1].filter($matches[2]).$matches[3];
}