You cannot encode this in the replacement string. As PoloRM suggested, you could use preg_replace_callback
specifically for your last replacement instead:
function decode_html($matches)
{
return '[code]'.html_entity_decode($matches[1]).'[/code]';
}
$str = '<code> < > </code>';
$str = preg_replace_callback('/(?:\<code*\>([^\<]*)\<\/code\>)/', 'decode_html', $str);
Equivalently, using create_function
:
$str = preg_replace_callback(
'/(?:\<code*\>([^\<]*)\<\/code\>)/',
create_function(
'$matches',
'return \'[code]\'.html_entity_decode($matches[1]).\'[/code]\';'
),
$str
);
Or, as of PHP 5.3.0:
$str = preg_replace_callback(
'/(?:\<code*\>([^\<]*)\<\/code\>)/',
function ($matches) {
return '[code]'.html_entity_decode($matches[1]).'[/code]';
},
$str
);
But note that in all three cases, your pattern is not really optimal. Firstly, you don't need to escape those <
and >
(but that is just for readability). Secondly, your first *
allows infinite repetition (or omission) of the letter e
. I suppose you wanted to allow attributes. Thirdly, you cannot include other tags within your <code>
(because [^<]
will not match them). In this case maybe you should go with ungreedy repetition instead (I also changed the delimiter for convenience):
~(?:<code[^>]*>(.*?)</code>)~
As you can already see, this is still far from perfect (in terms of correctly matching the HTML in the first place). Hence, the obligatory reminder: don't use regex to parse HTML. You will be much better off, using a DOM parser. PHP brings a built-in one, and there is also this very convenient-to-use 3rd-party one.