如何使用preg_replace_callback?

Mar*_*ark 36 php preg-replace preg-replace-callback

我有以下HTML语句

[otsection]Wallpapers[/otsection]
WALLPAPERS GO HERE

[otsection]Videos[/otsection]
VIDEOS GO HERE
Run Code Online (Sandbox Code Playgroud)

我想要做的是用html div替换[otsection]标签.问题是我想从1-> 2-> 3等增加div的id.

例如,上述声明应该翻译成

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

<div class="otsection" id="2">Videos</div>
VIDEOS GO HERE
Run Code Online (Sandbox Code Playgroud)

据我所知,最好的方法是通过preg_replace_callback来增加每个替换之间的id变量.但经过1小时的工作后,我无法让它发挥作用.

对此的任何帮助将不胜感激!

Nie*_*sol 47

使用以下内容:

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

特别要注意我使用了一个static变量.此变量在函数调用期间持续存在,这意味着每次调用函数时它都会递增,这对于每个匹配都会发生.

另外,请注意我ots在ID之前.元素ID不应以数字开头.


对于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);
Run Code Online (Sandbox Code Playgroud)

  • @MichaelProbst这就是为什么你应该升级到具有匿名功能支持(5.3或更新版本)的PHP版本.如果你仍在使用5.2,那么你的问题比伪装的'eval`更大;) (2认同)

Ama*_*ali 27

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

什么是preg_replace_callback()

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

我应该什么时候使用它?

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

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

如何使用它?

这是一个例子来说明函数的用法.在这里,我们尝试将日期字符串从YYYY-MM-DD格式转换为DD-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;
Run Code Online (Sandbox Code Playgroud)

这里,我们的正则表达式模式搜索格式的日期字符串,NNNN-NN-NN其中N可以是一个数字,范围从0- 9(\d是字符类的简写表示[0-9]).将调用回调函数并传递给定字符串中的匹配元素数组.

最终结果将是:

22-02-2014
Run Code Online (Sandbox Code Playgroud)

注意:以上示例仅用于说明目的.您不应该使用解析日期.使用DateTime::createFromFormat()DateTime::format()替代.这个问题有更多细节.