【问题标题】:preg_replace is not removing content between custom tagspreg_replace 不会删除自定义标签之间的内容
【发布时间】:2013-04-25 04:55:01
【问题描述】:

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

[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>   

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

【问题讨论】:

  • 改用preg_replace_all。
  • @Cylian 在 php 中没有像 preg_replace_all 这样的 preg_replace 的第三个参数值,如果设置为 -1,它将替换无限出现的 preg
  • @PHPSeeker,我冒昧地将正则表达式分隔符更改为 ~ 并取消转义正则表达式中的斜线。我发现这种方式更容易阅读,而且当您的代码易于阅读时,您往往会更快地获得更多响应。如果您不喜欢它,请随时将其改回。

标签: php regex preg-replace


【解决方案1】:

您忘记了 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.

【讨论】:

  • 是的,它的工作感谢伙伴的回答,我错过了s 标志:)
【解决方案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);

【讨论】:

  • 这会引发错误,您必须正确转义方括号,而且匹配多行时会失败,请使用s 修饰符。
  • @HamZaDzCyber​​DeV:我没有任何错误。我已经测试过了。右方括号不需要转义,也可以在类中打开方括号,这里不需要 \s 修饰符,因为我不使用点。
  • 我原谅你……这次!
猜你喜欢
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多