Preg_replace仅替换第一个匹配

时间:2014-03-11 09:23:29

标签: php regex preg-replace

我对正则表达式表达式相对较新,我遇到了这个问题。我搜索了这个网站,发现没有任何效果。

我希望它删除<br /><div class='quote'>之间的所有</div>。原因是CSS无论如何都保留了空格,我想删除用户放入的任何额外的换行符。

例如,说我有这个:

<div class='quote'>First line of text<br />
Second line of text<br />
Third line of text</div>

我一直在尝试使用此功能移除<br />标记。

$TEXT = preg_replace("/(<div class='quote'>(.*?))<br \/>((.*?)<\/div>)/is","$1$3",$TEXT);

这在一定程度上起作用,因为结果是:

<div class='quote'>First line of text
Second line of text<br />
Third line of text</div>

但是它不会删除第二个<br />。有人可以帮忙吗?我认为它可能是我想念的小东西:)

谢谢!

4 个答案:

答案 0 :(得分:0)

如果你想只清除一个div块中的所有br-s,你需要首先捕获div块内的内容,然后清除所有的br-s。

您的正则表达式中只有一个<br />,因此它只替换了一个<br />

你需要这样的东西:

function clear_br($a)
{
    return str_replace("<br />", "", $a[0]);
}

$TEXT = preg_replace_callback("/<div class='quote'>.*?<br \/>.*?<\/div>/is", "clear_br", $TEXT);

答案 1 :(得分:0)

它确实替换了不止一次,因为你没有在preg_replace中使用第四个参数,所以它是“无限制”并且将被替换不止一次。它只替换了一次,因为你在你的正则表达式中指定了包裹<div>,所以它只匹配你的字符串一次,因为你的字符串只有一次这样的包裹<div>

假设我们已经拥有:

<div class='quote'>First line of text<br />
Second line of text<br />
Third line of text</div>

我们可以简单地做一些事情:

$s = "<div class='quote'>First line of text<br />\nSecond line of text<br>\nThird line of text</div>";

echo preg_replace("{<br\s*/?>}", " ", $s);

\s*用于可选空格,因为它是<br/>会是什么? /?适用于可选/,因为它可能是<br>。如果系统为您输入了<br />,并且您确定它们将采用此格式,那么您可以使用更简单的正则表达式。

需要注意的是,我实际上会用空格替换它,因为对于hello<br>world,如果没有空格用作替换文本,那么它将变为helloworld并且它合并了两个单词合而为一。

(如果您还没有提取此<div ... > ... </div>,那么您可能需要首先使用HTML解析器执行此操作,例如,如果原始内容是整个网页(我们使用解析器,因为如果此外<div>...</div>内的内容有<div></div>,甚至还有嵌套?如果内部没有<div>,那么使用正则表达式提取它更容易))

答案 2 :(得分:0)

我没有得到你的 [。*?] :你在这里说你想要“任何次数为零或一次”的任何特征。所以你可以简单地说“任何次数的任何特征”:。*

function clear_br($a){ return str_replace("<br />","",$a); }
$TEXT = preg_replace("/(<div class='quote'>.*<br \/>.*<\/div>)/",clear_br($1), $TEXT);

否则这应该有效

答案 3 :(得分:0)

您必须小心如何捕获包含br元素的div。动静能量先生指出你需要注意嵌套的div。我的解决方案没有。

<?php
$subject ="
<div>yomama</div>
<div class='quote'>First line of text<br />
        Second line of text<br />
        Third line of text</div>
<div>hasamustache</div>
";


$result = preg_replace_callback( '@<div[^>]+class.*quote.*?</div>@s', 
function ($matches) {
    print_r($matches);
    return preg_replace('@<br ?/?>@', '', $matches[0]);

}
        , $subject);

echo "$result\n";
?>
  • @用作正则表达式分隔符,而不是传统的/
  • <div[^>]+会阻止yomama div匹配,因为我们有<div.*class.*quote,因为我们有s修饰符(多行匹配)。
  • 报价。*?表示非贪婪的匹配,以防止hasamustache</div>被捕获。

所以策略是将字符串中的引号div与换行符匹配,并在其上运行一个将终止所有br标记的函数。

输出:

output