如何在preg_replace_callback中转义接受一个或两个参数的简码?

时间:2019-03-13 14:43:22

标签: php preg-replace-callback

这里是the function,我正在用来声明一个短代码[warning],该代码可能包含一个或两个参数[warning](!parameter1!)(!parameter2!)[warning](!parameter1!)

function warning($text) {
    return preg_replace_callback('/\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> '.$m[1].' </h2><div class="alert-body"><p> '.$m[2].' </p></div></div></div>';
            } else {
                return '<div class="alert alert-error"><div class="alert-content"> '.$m[1].' </div></div>';
            }
        }
        , $text);
}
add_filter('the_content', 'warning');
add_filter( 'the_excerpt', 'warning');

我正在尝试修改此代码,以便能够转义该短代码,以便论坛中的用户可以使用它向他人解释如何使用此短代码,这是我正在尝试的方法这样做(基于answerstr_replace类似的问题)知道我正在尝试使用反斜杠\[warning](!par1!)\[warning](!par1!)(!par2!)

function warning($text) {
    $text = preg_replace_callback('/[^\\\\]\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> '.$m[1].' </h2><div class="alert-body"><p> '.$m[2].' </p></div></div></div>';
            } else {
                return '<div class="alert alert-error"><div class="alert-content"> '.$m[1].' </div></div>';
            }
        }
        , $text);
    $text = preg_replace_callback('/\\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '[warning](!'.$m[1].'  !)(!' .$m[2]. '!)';
            } else {
                return '[warning](!'.$m[1].'!)';
            }
        }
        , $text); 
    return $text;       
}
add_filter('the_content', 'warning');
add_filter( 'the_excerpt', 'warning');

第一次调用preg_replace_callback是搜索\之前没有的所有实例,第二个是使用\搜索那些实例。

我正在使用PHP <5.6。因此,我无法使用preg_replace_callback_array,即使我认为相同的更正应适用于这两个功能。

有什么主意吗?

1 个答案:

答案 0 :(得分:0)

分析输出后,我能够看到问题的原因以及为什么替换工作做得不好。这是由于使用了[^\\\\]\\。第一个导致这种格式<p<div class="alert alert-error"> ...的输出,第二个导致查找要替换的文本不正确。所以做了一些修改

function warning_f($text) {
    $text = preg_replace_callback('/(?<!\\\\)\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> '.$m[1].' </h2><div class="alert-body"><p> '.$m[2].' </p></div></div></div>';
            } else {
                return '<div class="alert alert-error"><div class="alert-content"> '.$m[1].' </div></div>';
            }
        }
        , $text);
    $text = preg_replace_callback('/\\\\\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/', 
        function ($m) {
            if (isset($m[2])) {
                return '[warning](!'.$m[1].'  !)(!' .$m[2]. '!)';
            } else {
                return '[warning](!'.$m[1].'!)';
            }
        }
        , $text); 
    return $text;       
}
add_filter('the_content', 'warning_f');
add_filter( 'the_excerpt', 'warning_f');

升级到php 7.2后,我使用了preg_replace_callback_array,这是相应的代码

function warning_f($text) {
    $text=preg_replace_callback_array(
        [
        '/(?<!\\\\)\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/' 
        => function ($m) {
                return '<div class="alert alert-error"><div class="alert-content"><h2 class="alert-title"> '.$m[1].' </h2><div class="alert-body"><p> '.$m[2].' </p></div></div></div>';
            } else {
                return '<div class="alert alert-error"><div class="alert-content"> '.$m[1].' </div></div>';
            }
        },
        '/\\\\\[warning\]\s*\(!(.*?)!\)(?:\s*\(!(.+?)!\))?/' 
        => function ($m) {
            if (isset($m[2])) {
            return '[warning](!'.$m[1].'  !)(!' .$m[2]. '!)';
            } else {
            return '[warning](!'.$m[1].'!)';
            }
        }
        ],
        $text);
    return $text;
}
add_filter('the_content', 'warning_f');
add_filter( 'the_excerpt', 'warning_f');