preg_replace不会删除自定义标记之间的内容

时间:2013-05-01 06:52:55

标签: php regex preg-replace

我想要执行正则表达式的内容是:

[NON-CA]
This is for Non CA
<b> In a New Line </b> 
[/NON-CA]
[CA]
This is for CA
[/CA]

我想根据加拿大的国家/地区代码删除内容,因此,如果用户来自加拿大,则只有CA部分可供他使用,而其他部分仅可见NON-CA部分将是可见的。标签之间的内容可以是换行符,空格,特殊字符,HTML标记,HTML实体。这是我写的代码:

<?php
    $content = "[NON-CA]This is for Non CA<b> In a New Line </b> [/NON-CA]    [CA]This is for CA[/CA]";
    $CApattern = "~\[CA\](.*?)\[/CA\]~";
    $NonCApattern = "~\[NON-CA\](.*?)\[/NON-CA\]~";                       
    $NonCApatternsReplacement = array();
    $Replacepatterns = array();        
    $Replacepatterns[] = "~\[CA\]~";
    $Replacepatterns[] = "~\[/CA\]~";
    $NonCApatternsReplacement[] = "~\[NON-CA\]~";
    $NonCApatternsReplacement[] = "~\[/NON-CA\]~"; 

    if($country_code ==  "CA"){ //if its the user of country Canada remove the NON-CA Tag                                
        $result_p1 = preg_replace($NonCApattern, "", $content, -1, $count);                                                                                                                                
        $result_p2 = preg_replace($Replacepatterns, "", $result_p1, -1);
     }
     else{ //if user is not from CANADA remove CA tag and Text                                     

        $result_p1 = preg_replace($NonCApatternsReplacement, "", $content, -1);                                                             
        $result_p2 = preg_replace($CApattern,"", $result_p1, -1, $count);                                                                                                                     
     } 
     echo $result_p2
?>

因此,如果有加拿大用户,则会生成以下内容:

[NON-CA]
This is for Non CA
<b> In a New Line </b> 
[/NON-CA]
This is for CA

其实应该是这样的:

This is for CA

如果非加拿大用户到达,它会生成如下结果文本:

This is for Non CA
<b> In a New Line </b>     
[CA]
This is for CA
[/CA]

其实应该是这样的:

This is for Non CA
<b> In a New Line </b>   

根据条件,不会替换/删除相应用户不应该看到的内容部分。我的正则表达式有问题吗?

2 个答案:

答案 0 :(得分:4)

您忘记了s modifier,您还会将换行符与点.匹配。

 s (PCRE_DOTALL)
    If this modifier is set, a dot metacharacter in the pattern matches all characters,
    including newlines. Without it, newlines are excluded.
    This modifier is equivalent to Perl's /s modifier.
    A negative class such as [^a] always matches a newline character,
    independent of the setting of this modifier. 

我虽然提供了更短的代码:

$string = '[NON-CA]
This is for Non CA
<b> In a New Line </b> 
[/NON-CA]
[CA]
This is for CA
[/CA]';

$remove = 'NON-CA';
$result = preg_replace('/\['.$remove.'\].*?\[\/'.$remove.'\]/s', '', $string);
echo $result;

Online demo

答案 1 :(得分:2)

您可以在一次替换中完成所有这些:

$country_code = 'CA'; // for example

$content = <<<LOD
[NON-CA]This is for Non CA<b> In a New Line </b> [/NON-CA]
[CA]This is for CA[/CA]
LOD;

$kr = array('CA', 'NON-CA'); // switch keep/remove
if ($country_code == 'CA') $kr = array_reverse($kr); 

$pattern = '~\[(?:' . $kr[0] . '][^[]++\[/' . $kr[0] . ']|/?' . $kr[1] . '])~';

$result = preg_replace($pattern, '', $content);