如何使用preg_replace_callback?

2022-08-30 11:49:57

我有以下 HTML 语句

[otsection]Wallpapers[/otsection]
WALLPAPERS GO HERE

[otsection]Videos[/otsection]
VIDEOS GO HERE

我试图做的是用html div替换[otsection]标签。问题是我想将 div 的 id 从 1->2->3 递增,依此类推。

因此,例如,上述语句应转换为

<div class="otsection" id="1">Wallpapers</div>
WALLPAPERS GO HERE

<div class="otsection" id="2">Videos</div>
VIDEOS GO HERE

据我所知,最好的方法是通过preg_replace_callback在每次替换之间增加id变量。但是经过1个小时的工作,我只是无法让它工作。

任何这方面的帮助将不胜感激!


答案 1

使用以下命令:

$out = preg_replace_callback(
    "(\[otsection\](.*?)\[/otsection\])is",
    function($m) {
        static $id = 0;
        $id++;
        return "<div class=\"otsection\" id=\"ots".$id."\">".$m[1]."</div>";
    },
    $in);

特别要注意的是,我使用了一个变量。此变量在对函数的调用中持续存在,这意味着每次调用函数时都会递增,每次匹配都会发生这种情况。static

另请注意,我在 ID 前面附加了元素 ID,元素 ID 不应以数字开头。ots


对于 5.3 之前的 PHP:

$out = preg_replace_callback(
    "(\[otsection\](.*?)\[/otsection\])is",
    create_function('$m','
        static $id = 0;
        $id++;
        return "<div class=\"otsection\" id=\"ots".$id."\">".$m[1]."</div>";
    '),
    $in);

答案 2

注意:以下内容旨在作为一般答案,并不试图解决OP的特定问题,因为它之前已经解决过

什么是preg_replace_callback()

此函数用于执行正则表达式搜索和替换。它类似于str_replace(),但它搜索用户定义的正则表达式模式,而不是纯字符串,然后对匹配的项应用回调函数。如果找到匹配项,该函数将返回修改后的字符串,否则返回未修改的字符串。

我应该何时使用它?

preg_replace_callback()preg_replace() 非常相似 - 唯一的区别是,您不是为第二个参数指定替换字符串,而是指定一个函数。callback

当您想要执行简单的正则表达式搜索和替换时使用。当您想要做的不仅仅是更换时,请使用。请参阅下面的示例,了解其工作原理。preg_replace()preg_replace_callback()

如何使用它?

下面是一个示例,用于说明该函数的用法。在这里,我们尝试将日期字符串从格式转换为.YYYY-MM-DDDD-MM-YYYY

// our date string
$string  = '2014-02-22';

// search pattern
$pattern = '~(\d{4})-(\d{2})-(\d{2})~';

// the function call
$result = preg_replace_callback($pattern, 'callback', $string);

// the callback function
function callback ($matches) {
    print_r($matches);
    return $matches[3].'-'.$matches[2].'-'.$matches[1];
}

echo $result;

在这里,我们的正则表达式模式搜索格式的日期字符串,其中可能是从 - (是字符类的速记表示)的数字。回调函数将被调用并传递给定字符串中匹配元素的数组。NNNN-NN-NNN09\d[0-9]

最终结果将是:

22-02-2014

注意:以上示例仅用于说明目的。不应 使用 来分析日期。请改用 DateTime::createFromFormat()DateTime::format()。这个问题有更多细节。


推荐