【问题标题】:How to use preg_replace_callback?如何使用 preg_replace_callback?
【发布时间】:2012-06-24 03:46:47
【问题描述】:

我有以下 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 小时的工作后,我无法让它工作。

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

【问题讨论】:

    标签: php preg-replace preg-replace-callback


    【解决方案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 前添加了 ots。元素 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);
    

    【讨论】:

    • 你如何让$in 填充主题?
    • @SheikhHeera 那应该已经存在了。我通常使用$in$out 来显示数据的输入和输出位置。
    • 感谢它看起来很棒并且应该可以工作,但我不断收到意外的 T_FUNCTION 错误,但引号和转义引号看起来都不错。 ideone.com/K71TV
    • 那是因为您使用的是旧版本的 PHP。我将使用向后兼容的版本进行编辑。
    • @MichaelProbst 这就是为什么您应该升级到支持匿名函数的 PHP 版本(5.3 或更高版本)。如果您仍在使用 5.2,那么您遇到的问题比变相的错误eval 更大;)
    【解决方案2】:

    注意:以下是一个一般性的答案,并不试图解决 OP 的具体问题,因为它已经是addressed before

    什么是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;
    

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

    最终结果将是:

    22-02-2014
    

    注意:以上示例仅用于说明目的。您不应用于解析日期。请改用DateTime::createFromFormat()DateTime::format()This question 有更多详情。

    【讨论】:

    • 一旦你知道它似乎很明显,但如果你刚开始使用 preg_ 函数可能值得注意的是,在示例中 $matches 从 1 而不是 0 开始,因为0 包含匹配的整个字符串。见stackoverflow.com/a/14383726/957246
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2013-03-17
    相关资源
    最近更新 更多