PHP preg_match игнорировать внутри определенных элементов - PullRequest
0 голосов
/ 06 февраля 2019

Я пишу regex, где мне нужно отфильтровать контент, чтобы отформатировать его типографику.Пока что мой код, похоже, правильно фильтрует мой контент, используя preg_replace, но я не могу понять, как этого избежать для контента, заключенного в определенные теги, скажем <pre>.

В качестве ссылки, это должно использоваться в фильтре WordPress the_content, поэтому мой текущий код выглядит так:

function my_typography( $str ) {
    $ignore_elements = array("code", "pre");

    $rules = array(
        "?" => array("before"=> "&thinsp;", "after"=>""),
        // the others are stripped out for simplicity
    );

    foreach($rules as $rule=>$params) {
        // Pseudo :
        //    if( !in_array( $parent_tag, $ignore_elements) {
        // /Pseudo


        $formatted = $params['before'] . $rule . $params['after'];
        $str = preg_replace( $rule, $formatted, $str );


        // Pseudo :
        //    }
        // /Pseudo
    }

    return $str;
}
add_filter( 'the_content',  'my_typography' );

В основном:

<code><p>Was this filtered? I hope so</p>
<pre>Was this filtered? I hope not.

должно стать

<code><p>Was this filtered&thinsp;? I hope so</p>
<pre>Was this filtered? I hope not.

1 Ответ

0 голосов
/ 06 февраля 2019

Вам необходимо заключить поисковое регулярное выражение в разделитель регулярных выражений в preg_replace и вызвать preg_quote, чтобы экранировать все специальные символы регулярного выражения, такие как ?, ., *, + и т. Д .:

$str = preg_replace( '~' . preg_quote($rule, '~') . '~', $formatted, $str );

Полный код:

function my_typography( $str ) {
    $ignore_elements = array("code", "pre");

    $rules = array(
        "?" => array("before"=> "&thinsp;", "after"=>""),
        // the others are stripped out for simplicity
    );

    foreach($rules as $rule=>$params) {
        // Pseudo :
        //    if( !in_array( $parent_tag, $ignore_elements) {
        // /Pseudo


        $formatted = $params['before'] . $rule . $params['after'];
        $str = preg_replace( '~' . preg_quote($rule, '~') . '~', $formatted, $str );


        // Pseudo :
        //    }
        // /Pseudo
    }

    return $str;
}

Выход:

<code><p>Was this filtered&thinsp;? I hope so</p>
<pre>Was this filtered&thinsp;? I hope not.
...