【问题标题】:Preg_replace and Preg_replace_callbackPreg_replace 和 Preg_replace_callback
【发布时间】:2016-02-07 07:00:40
【问题描述】:

我正在更新我的编码并从 preg_replace 转向函数 preg_replace_callback。首先我使用了两个数组,它们替换了一段文本中的所有匹配项。

我已经设置了以下新代码,但遇到了一些问题:

<?php
$inhoud = " dit is een test versie, waarin [alum] staat [alum] & [fotoalbums] om [intern=test]te[/intern] vervangen<p>";

function parse_callback($match) {
        $hit = $match[0];
        switch ($hit){
                case '[alum]': 
                        return "<a href=\"/linktype1/\">link1</a>";
                        break;
                case '[fotoalbums]':
                        return "<a href=\"/linktype2/\">link2</a>";
                        break;
                case '[intern]':
                        return "<a href=\"". $match[1] ."\">$match[2]</a>";
                        break;
                default:
                        //return "UNKNOWN:$match";
                        return var_dump($match);
        }
}

$Patroon = "'\[intern=(.*?)\](.*?)\\[\/intern\]'";
$Patroon = "'\[fotoalbums\]'";
$Patroon = "'\[alum\]'";

$inhoud = preg_replace_callback($Patroon, parse_callback, $inhoud);
?>

$Patroon 中的后两个没有问题,这些将被更新,但我无法更新第一个,因为找到的匹配项将是完整的字符串。 $match 还将包含来自 $inhoud 的文本片段,其中匹配 (.*?),但我无法在 switch 中处理这些。

有关如何解决此问题或更好的编码方法的任何建议。 上面的例子只是要匹配的几个选项,实际列表要大得多。

【问题讨论】:

    标签: php regex preg-replace-callback


    【解决方案1】:

    首先,您应该将函数名作为字符串传递:"parse_callback"

    如您所见,match[0] 将返回整个匹配文本 ("[intern=test]te[/intern]")。您可以在group 中捕获标签名称:

    $Patroon = "'\[(intern)=(.*?)\](.*?)\[/intern\]'";
    
    • 注意(intern) 中的括号

    这样,$match[1]会返回标签名。

    并对所有模式使用这种方法:

    $Patroon = array(
        "'\[(intern)=(.*?)\](.*?)\[/intern\]'",
        "'\[(fotoalbums|alum)\]'"
    );
    

    代码

    <?php
    $inhoud = " dit is een test versie, waarin [alum] staat [alum] & [fotoalbums] om [intern=test]te[/intern] vervangen<p>";
    
    function parse_callback($match) {
            //check the value of the first capture
            $hit = $match[1];
            switch ($hit){
                    case 'alum': 
                            return "<a href=\"/linktype1/\">link1</a>";
                            break;
                    case 'fotoalbums':
                            return "<a href=\"/linktype2/\">link2</a>";
                            break;
                    case 'intern':
                            return "<a href=\"$match[2]\">$match[3]</a>";
                            break;
                    default:
                            //return "UNKNOWN:$match";
                            return var_dump($match);
            }
    }
    
    $Patroon = array(
        "'\[(intern)=(.*?)\](.*?)\[/intern\]'",
        "'\[(fotoalbums|alum)\]'"
    );
    
    $inhoud = preg_replace_callback($Patroon, "parse_callback", $inhoud);
    
    echo $inhoud;
    ?>
    

    输出

     dit is een test versie, waarin <a href="/linktype1/">link1</a> staat <a href="/linktype1/">link1</a> & <a href="/linktype2/">link2</a> om <a href="test">te</a> vervangen<p>
    

    ideone demo

    【讨论】:

    • 我很高兴。另请记住,您可以轻松地将最后 2 个模式合并为 1 个。
    • 你的意思是,你可以将最后两个模式合并为1?不知道我是否完全理解你的意思。
    • @Ralf 它们都可以合并为"'\[(fotoalbums|alum)\]'"。我编辑了答案以表明我的意思。
    猜你喜欢
    • 2017-06-02
    • 1970-01-01
    • 2014-04-27
    • 2015-08-09
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多