的preg_replace不删除自定义标签

问题描述:

上,我要执行正则表达式的内容之间的内容是这样的:的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> 

它不更换/移除根据条件应该是不可见的相应用户的内容的一部分。我的正则表达式有什么问题吗?

+1

使用'preg_replace_all'代替。 – Cylian 2013-05-01 07:03:04

+1

@Cylian没有什么像preg_replace_all在PHP中preg_replace的第三个参数值,如果设置为-1它将取代无限次出现的preg – Seeker 2013-05-01 07:11:43

+0

@PHPSeeker,我冒昧地将正则表达式分隔符更改为'〜',并且在内部使用了正斜杠分隔符正则表达式。我发现以这种方式阅读起来要容易得多,而且当您的代码易于阅读时,您会更快地获得更多回复。如果您不喜欢,请随时将其改回。 – 2013-05-01 08:44:51

您忘记了smodifier与此相匹配,您还将换行符换成.

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

是的,它的工作感谢队友的答案是我错过了's'国旗:) – Seeker 2013-05-01 12:55:01

你可以做到这一切在一个替换:

$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); 
+1

这会引发错误,你必须正确地转义方括号,此外它会失败匹配多行,使用's'修饰符。 – HamZa 2013-05-01 08:41:47

+1

@HamZaDzCyber​​DeV:我没有任何错误。我已经测试过它。关闭方括号不需要转义,也可以在类中打开方括号,而\ s修饰符在这里不需要,因为我不使用点。 – 2013-05-01 08:49:02

+0

对不起,我使用了一个糟糕的在线PHP键盘。 +1 :) – HamZa 2013-05-01 08:51:51