Как избежать шорткода, принимающего один или два параметра в preg_replace_callback? - PullRequest
0 голосов
/ 13 марта 2019

Вот функция Я использую для объявления шорткода [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.Поэтому я не могу использовать <code>preg_replace_callback_array, даже думаю, что одна и та же коррекция должна работать с двумя функциями.

Есть идеи?

1 Ответ

0 голосов
/ 29 марта 2019

Проанализировав вывод, я смог увидеть причину проблемы и почему замена не выполнена. Это связано с использованием [^\\\\] и \\. Первый вызывал вывод этой формы <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');
...