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

How to escape a shortcode accepting one or two parameters in preg_replace_callback?

这是 我用来声明一个短代码 [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');

我正在尝试修改此代码以便能够转义此简码,以便我论坛中的用户可以使用它来向其他人解释如何使用此简码,这就是我的方法我正在尝试这样做(基于 str_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,即使我认为同样的修正应该适用于这两个函数。

有什么想法吗?

分析输出后,我能够看到问题的原因以及替换没有做好的原因。这是由于使用了 [^\\]\。第一个导致此形式的输出 <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');

升级到php7.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');