删除html属性之间的空格

时间:2014-04-08 19:38:32

标签: php html regex preg-replace str-replace

我试图删除HTML属性中的空格/空白字符:

初​​始

<p style="font-size: 1.5em; color: navy;">
 Text With Spaces
<p style="font-size: 1.2em; color: navy;"> 

所需

<p style="font-size:1.5em;color:navy;">
 Text with spaces
<p style="font-size:1.2em;color:navy;">

首先,我尝试使用preg_replace删除所有空格,然后执行查找和替换以插入但删除了文档中的所有空格

$cont = preg_replace( '/\s+/', '', $original);
$cont2 = str_replace('<p', "<p ", $cont2);

不正确的

<p style="font-size:1.5em;color:navy;">
 Textwithspaces
<p style="font-size:1.5em;color:navy;">

1 个答案:

答案 0 :(得分:1)

由于您要删除任何空格,除了紧跟在标记名称之后的空格之外,这有点棘手,但当然可以这样做。

$string = '<p style="font-size: 1.5em; color: navy;">
 Text With Spaces
<p style="font-size: 1.2em; color: navy;"> ';

$string = preg_replace_callback('~<([A-Z0-9]+) \K(.*?)>~i', function($m) {$replacement = preg_replace('~\s*~', '', $m[0]); return $replacement;}, $string);

print $string;

我在这里做的是寻找一个开头的HTML括号<,后跟一个标签名称,后跟一个空格。对于代码名称,我使用允许字母[]和数字A-Z的字符类0-9。它必须至少包含其中一个字符+,但可能包含多个字符......一直到达空格。然后,我告诉REGEX从此时开始记住我们的匹配\K并查找任何字符.,因为它可以找到它*的所有次数,一直直到它碰到我们的REGEX ?中的下一件事。在这种情况下,我们REGEX中的下一个内容是结束HTML括号>

然后我使用preg_replace_callback来评估它找到的每个匹配项。对于每个匹配,它会查找任意数量的空格\s*并将其替换为空。

这将为您提供所要求的内容:

<p style="font-size:1.5em;color:navy;">
  Text With Spaces
<p style="font-size:1.2em;color:navy;"> 

然而,它还会产生一些其他副作用。举个例如这样的字符串:

$string = '<p style="font-size: 1.5em; color: navy;"><a href="http://www.google.com" style="color: orange;">Google Website</a>
 Text With Spaces
<p style="font-size: 1.2em; color: navy;"> <img src="http://www.google.com/images/logo.gif" width=100 height=100>';

使用上面的正则表达式会得到如下结果:

<p style="font-size:1.5em;color:navy;"><a href="http://www.google.com"style="color:orange;">Google Website</a>
 Text With Spaces
<p style="font-size:1.2em;color:navy;"> <img src="http://www.google.com/images/logo.gif"width=100height=100>

为了解决这个问题,你必须做几场比赛&amp;替换,因为您需要查找项目周围的引号/标记,但是,这些项目需要在HTML标记内。你不能做这样的事情:

<.*?"(.*?)".*?>

因为它不会像"http://www.google.com" style="color:orange;"那样匹配HTML标记内有多组引号的内容。为了解决这个问题,我首先拿出标签,然后在我拿到标签之后,拉出每组报价之间的内容进行评估。

$string = preg_replace_callback('~<(.*?)>~i', 

    function($m) {

        $return_var = preg_replace_callback('~\'|".*?\'|"~', function ($r) {$v = preg_replace('~\s*~', '', $r[0]); return $v;}, $m[0]);
        return $return_var;
    }, 

    $string);

print $string;

这基本上是两个preg_replace_callbacks推到一个声明中。第一个告诉函数对任何标签进行操作。第二个告诉函数对这些HTML标记中的引号/标记内的任何内容进行操作。

Here is a demo so you can compare the different options