<?php
$str = '<chunk>[[$chunk.name.test]]</chunk><chunk>[[!$tpl.test.name]]</chunk><chunk>[[$test]]</chunk>';
$replace = '<span data-element="$1" name="$3">$2</span>';
echo preg_replace("/<(\w+)>(\[\[[$!]+([^\]]+)\]\])<\/(\w+)>/u", $replace, $str);
Вывод:
$ php replace.php
<span data-element="chunk" name="chunk.name.test">[[$chunk.name.test]]</span>
<span data-element="chunk" name="tpl.test.name">[[!$tpl.test.name]]</span>
<span data-element="chunk" name="test">[[$test]]</span>
Вариант с $allow:
<?php
$str = '<chunk>[[$chunk.name.test]]</chunk><chunk>[[!$tpl.test.name]]</chunk><chunk>[[$test]]</chunk>';
$replace = '<span data-element="$1" name="$3">$2</span>';
$allow = 'chunk.name.test|test';
echo preg_replace("/<(\w+)>(\[\[[$!]+((?:{$allow}))\]\])<\/(\w+)>/u", $replace, $str);
Вывод:
$ php replace.php
<span data-element="chunk" name="chunk.name.test">[[$chunk.name.test]]</span>
<chunk>[[!$tpl.test.name]]</chunk>
<span data-element="chunk" name="test">[[$test]]</span>
Поиграйтесь тут:
https://regex101.com/r/gI5rE3/1