0

我有这个 preg_replace 模式和替换:

$patterns = array(
    "/<br\W*?\/>/",
    "/<strong>/",
    "/<*\/strong>/",
    "/<h1>/",
    "/<*\/h1>/",
    "/<h2>/",
    "/<*\/h2>/",
    "/<em>/",
    "/<*\/em>/",
    '/(?:\<code*\>([^\<]*)\<\/code\>)/',
);
$replacements = array(
    "\n",
    "[b]",
    "[/b]",
    "[h1]",
    "[/h1]",
    "[h2]",
    "[/h2]",
    "[i]",
    "[/i]",
    '[code]***HTML DECODE HERE***[/code]',
);

在我的字符串中,我想要html_entity_decode这些标签之间的内容: <code> &lt; $gt; </code>但保留我的数组结构以进行 preg 替换

所以这个:<code> &lt; &gt; </code>将是这个:[code] < > [/code]

任何帮助将不胜感激,谢谢!

4

2 回答 2

1

您不能在替换字符串中对此进行编码。正如 PoloRM 建议的那样,您可以preg_replace_callback专门用于最后一次替换:

function decode_html($matches)
{
    return '[code]'.html_entity_decode($matches[1]).'[/code]';
}

$str = '<code> &lt; &gt; </code>';
$str = preg_replace_callback('/(?:\<code*\>([^\<]*)\<\/code\>)/', 'decode_html', $str);

等效地,使用create_function

$str = preg_replace_callback(
    '/(?:\<code*\>([^\<]*)\<\/code\>)/',
    create_function(
       '$matches',
        'return \'[code]\'.html_entity_decode($matches[1]).\'[/code]\';'
    ),
    $str
);

或者,从 PHP 5.3.0 开始:

$str = preg_replace_callback(
    '/(?:\<code*\>([^\<]*)\<\/code\>)/',
    function ($matches) {
        return '[code]'.html_entity_decode($matches[1]).'[/code]';
    },
    $str
);

但请注意,在所有三种情况下,您的模式都不是最佳的。首先,您不需要转义这些<and >(但这只是为了便于阅读)。其次,您的第一个*允许无限重复(或省略)字母e。我想你想允许属性。第三,您不能在您的标签中包含其他标签<code>(因为[^<]它们不会匹配)。在这种情况下,也许您应该使用不贪婪的重复来代替(为方便起见,我还更改了分隔符):

~(?:<code[^>]*>(.*?)</code>)~

正如您已经看到的那样,这仍然远非完美(就首先正确匹配 HTML 而言)。因此,必须提醒:不要使用正则表达式来解析 HTML。使用 DOM 解析器会更好。PHP自带了一个,还有这个非常好用的3rd-party

于 2012-10-29T09:06:57.377 回答
0

看看这个:

http://www.php.net/manual/en/function.preg-replace-callback.php

您可以创建一个回调函数,将 html_entity_decode 功能应用于您的比赛。

于 2012-10-29T08:06:29.420 回答