PHP preg_match在某些元素中忽略

时间:2019-02-06 15:03:07

标签: php regex preg-match

我正在写一个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' );

基本上:

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

应成为

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

1 个答案:

答案 0 :(得分:1)

您需要在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;
}

输出:

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