【问题标题】:Remove whitespace from HTML从 HTML 中删除空格
【发布时间】:2011-07-18 17:51:00
【问题描述】:

我的 HTML 代码如下:

<div class="wrap">
    <div>
        <div id="hmenus">
            <div class="nav mainnavs">
                <ul>
                    <li><a id="nav-questions" href="/questions">Questions</a></li>
                    <li><a id="nav-tags" href="/tags">Tags</a></li>
                    <li><a id="nav-users" href="/users">Users</a></li>
                    <li><a id="nav-badges" href="/badges">Badges</a></li>
                    <li><a id="nav-unanswered" href="/unanswered">Unanswered</a></li>
                </ul>
            </div>
        </div>
    </div>
</div>

如何通过 PHP 去除标签之间的空格?

我们应该得到:

<div class="wrap"><div><div id="hmenus"><div class="nav mainnavs"><ul><li><a id="nav-questions" href="/questions">Questions</a></li><li><a id="nav-tags" href="/tags">Tags</a></li><li><a id="nav-users" href="/users">Users</a></li><li><a id="nav-badges" href="/badges">Badges</a></li><li><a id="nav-unanswered" href="/unanswered">Unanswered</a></li></ul></div></div></div></div>

【问题讨论】:

  • 我需要这个 - 一些电子邮件客户端在块元素之间存在空格错误。由于我在部署之前清理了 HTML,因此我需要一种方法来执行此操作。 @Czechnology 的正则表达式模式完美运行 - stackoverflow.com/a/5362207/582278.
  • 我想知道人们什么时候说这有什么意义。我也需要那个!总有一个原因
  • 我很惊讶没有人建议用这种方法来解决在元素之间存在空白时会中断的内联块问题(通常在网格系统中,但也在其他地方)。我还没有尝试过,但我来这里是为了在我的源代码中寻找 &lt;div class="box"&gt;...&lt;/div&gt;&lt;!-- [\n] --&gt;&lt;div class="box"&gt; 的替代品。
  • 我需要这个来针对我的代码编写测试 - 我正在重构并且空格可能会改变 - 我需要测试内容而不是空格。

标签: php html css whitespace


【解决方案1】:

使用正则表达式,例如:

>(\s).*?<

【讨论】:

    【解决方案2】:

    $html = preg_replace('~&gt;\s+&lt;~', '&gt;&lt;', $html);

    但我不明白这一点。如果您想减小数据大小,有更好的选择。

    【讨论】:

    • 好吧,在没有人看到一点的地方,其他人看到了很多,在盒子外面......:D这个正则表达式非常适合我。
    • 遗憾的是,这会将 &lt;b&gt;Hello&lt;/b&gt; &lt;i&gt;world&lt;/i&gt; 更改为 &lt;b&gt;Hello&lt;/b&gt;&lt;i&gt;world&lt;/i&gt;。检测空白是否有意义几乎是不可能的(内联和块级元素的列表会很方便)。
    • @SalmanA 是对的——你需要非常小心这个正则表达式,因为在某些情况下你不想删除标签之间的空格。这可能在&lt;pre&gt; &lt;code&gt; &lt;textarea&gt; &lt;script&gt; 内。这种模式也不会捕获文本内容中插入的大量空格/制表符,除非制表符位于两个标签之间。
    • @Simon,这个正则表达式正是 OP 写的他想要的:“删除标签之间的空格”。显然,这可能不是所有用途的最佳行为,但这取决于 OP。
    • 是的,它可能非常适合 OP 的情况,这很好。我只是认为对于那些在谷歌上搜索“从 HTML 中删除空格”(就像我一样)的人来说,这是一个重要的免责声明。
    【解决方案3】:

    RegEx 替换可以解决问题,例如:

    $result = preg_replace('!\s+!smi', ' ', $content);
    

    【讨论】:

    • 您使用的三个模式修饰符都不是必需的。
    • 是的,我的错,请查看其他答案以获取解决方案
    【解决方案4】:

    我无法删除此答案,但它不再相关,网络环境在 8 年内发生了如此大的变化,以至于它变得毫无用处。

    【讨论】:

    • 谷歌(在性能方面超过合格)通过他们的页面速度工具建议,这是值得的。当您使用 GZIP 时,它会压缩多余的不必要的空间。显然,如果您在 GZIP 之前删除这些空格,那么输出当然会更小更高效。答案是两者都有!
    • 这是真的。真正的问题归结为所需的规模和努力。请记住,您的时间是有限的,您的产品也是如此。如果您每月在 200kb 的 html 内容上获得 1000 次点击,请不要担心。如果您每月在 5mb 的 HTML 内容上提供 100 万次点击,那么就可以进行前所未有的优化。如果您有时间作为一种奢侈并想学习如何做到这一点,那就继续吧,但是在除 ySlow 之外的许多地方,去除空白以节省 50% 而不是 40% 并不会给您带来回报。
    • 我建议这个答案被否决,因为它不正确。 stackoverflow.com/questions/807119/gzip-versus-minify
    • @replete 是的,它高达 183b,整整小了 19b。这就是我要说的,在 1 000 000 次页面浏览之后,您在这种情况下可以节省 18 兆字节,并且您最终破坏了所有 PRE 标记内容。同样,您不需要去除 HTML 文件的格式,服务器会处理这个问题。你为什么要编辑文件本身?所有这些优化都应该由网络服务器完成,这就是它的目的。
    • 我在谷歌上搜索的所有内容,都会得到类似这样的可怕答案。这就像人们甚至不考虑别人的需求。也许他们提出这个问题的原因与缩小网站不同?例如,我必须在数据库中保存一些模板。我只是想为数据库压缩我的 html,而不是最终呈现。嘘。
    【解决方案5】:

    感谢您发布此问题。问题确实是在某些环境中处理空白错误。虽然正则表达式解决方案在一般情况下有效,但为了快速破解,删除前导空格并将标签添加到每行的末尾。 PHP 在结束 ?> 之后删除换行符。例如:

    <ul><?php ?>
    <li><a id="nav-questions" href="/questions">Questions</a></li><?php ?>
    <li><a id="nav-tags" href="/tags">Tags</a></li><?php ?>
    <li><a id="nav-users" href="/users">Users</a></li><?php ?>
    <li><a id="nav-badges" href="/badges">Badges</a></li><?php ?>
    <li><a id="nav-unanswered" href="/unanswered">Unanswered</a></li><?php ?>
    </ul>
    

    显然,由于各种原因,这不是最佳选择,但它可以解决局部问题,而不会影响整个工具链。

    【讨论】:

      【解决方案6】:
      $html = preg_replace('~>\s*\n\s*<~', '><', $html);
      

      我认为这是&lt;b&gt;Hello&lt;/b&gt; &lt;i&gt;world&lt;/i&gt; 问题的解决方案。这个想法是仅在有新行时删除空格。它适用于常见的 HTML 语法,即:

      <div class="wrap">
          <div>
          </div>
      </div>
      

      【讨论】:

      • 还有:$html = preg_replace('~>\s+
      【解决方案7】:

      array reduce 函数:

      $html = explode("\n", $html);
      function trimArray($returner, $value) {
          $returner .= trim($value);
          return $returner;
      }
      echo $html = array_reduce($html, 'trimArray');
      

      【讨论】:

        【解决方案8】:

        自从第一次提出这个问题以来已经有一段时间了,但我仍然认为有必要发布这个答案以帮助有同样问题的人。

        这些解决方案都不适合我,因此我想出了这个解决方案:使用output_buffer

        函数ob_start 接受一个回调作为参数,该参数在输出之前应用于整个字符串。因此,如果您在刷新输出之前从字符串中删除空格,那么您就完成了。

        /** 
         * Remove multiple spaces from the buffer.
         * 
         * @var string $buffer
         * @return string
         */
        function removeWhitespace($buffer)
        {
            return preg_replace('/\s+/', ' ', $buffer);
        }
        
        ob_start('removeWhitespace');
        
        <!DOCTYPE html>
        <html>
            <head></head>
            <body></body>
        </html>
        
        ob_get_flush();
        

        上面会打印如下内容:

        <!DOCTYPE html> <html> <head> </head> <body> </body> </html>
        

        希望对您有所帮助。

        如何在 OOP 中使用它

        如果您在 PHP 中使用面向对象的代码,您可能希望使用对象内部的回调函数。

        如果你有一个类,例如 HTML,你必须使用这个代码行

        ob_start(["HTML","removeWhitespace"]); 
        

        【讨论】:

        • Savas,这不是也删除了您需要的空间吗?说:&lt;div&gt;I need spaces here.&lt;/div&gt; &lt;div&gt;There's a space to remove before this div.&lt;/div&gt;
        • @Jomar:不,它会将多个空白字符的序列折叠成一个空格。此答案中的示例输出不正确;应该是&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt;&lt;/head&gt; &lt;body&gt;&lt;/body&gt; &lt;/html&gt;
        • @JomarSevillejo 我很抱歉,我更新了 Zilk 所说的输出。
        【解决方案9】:

        以防万一有人仍然需要这个,我从@Martin Angelova 的回复和@Savas Vedova 中创造了一个函数,结果也解决了我的问题:

        <?php 
           function rmspace($buffer){ 
                return preg_replace('~>\s*\n\s*<~', '><', $buffer); 
           };
        ?>
        <?php ob_start("rmspace");  ?>
           //Content goes in here 
        <?php ob_end_flush(); ?>
        

        注意:我没有在生产环境中测试性能损失

        【讨论】:

        • 相当快的正则表达式,我使用它。
        【解决方案10】:
        //...
        public function compressHtml($content)
        {
            $content = preg_replace('~>\s+<~', '><', $content);
            $content = preg_replace('/\s\s+/', ' ', $content);
            $i = 0;
            while ($i < 5) {
                $content = str_replace('  ', ' ', $content);
                $i++;    
            }
        
            return $content;
        }
        

        【讨论】:

        • 已测试,这就是解决方案!请参阅我的以下版本,了解有关忘记完整字符串修剪的返回的小更新。
        【解决方案11】:
        <?php
            define(COMPRESSOR, 1);
        
                function remove_html_comments($content = '') {
                    return preg_replace('/<!--(.|\s)*?-->/', '', $content);
                }
                function sanitize_output($buffer) {
                    $search = array(
                        '/\>[^\S ]+/s',  // strip whitespaces after tags, except space
                    '/[^\S ]+\</s',  // strip whitespaces before tags, except space
                    '/(\s)+/s'       // shorten multiple whitespace sequences
                  );
        
                  $replace = array(
                     '>',
                     '<',
                     '\\1'
                  );
        
                  $buffer = preg_replace($search, $replace, $buffer);
                  return remove_html_comments($buffer);
                }
                if(COMPRESSOR){ ob_start("sanitize_output"); }
            ?>
        
            <html>  
                <head>
                  <!-- comment -->
                  <title>Example   1</title>
                </head>
                <body>
                   <p>This is       example</p>
                </body>
            </html>
        
        
            RESULT: <html><head><title>Example 1</title></head><body><p>This is example</p></body></html> 
        

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        【解决方案12】:

        gpupo 的帖子为许多不同类型的间距格式提供了最简洁的解决方案。然而,最后却忘记了一个小而重要的部分!最后的字符串修剪:-p

        以下是经过测试的有效解决方案。

        function compress_html($content)
        {
            $i       = 0;
            $content = preg_replace('~>\s+<~', '><', $content);
            $content = preg_replace('/\s\s+/',  ' ', $content);
        
            while ($i < 5)
            {
                $content = str_replace('  ', ' ', $content);
                $i++;
            }
        
            return trim($content);
        }
        

        【讨论】:

          【解决方案13】:

          我为我使用了这个正则表达式,它就像一个魅力:

          preg_replace('/[ \t]+(?!="|\')/', '', $html);
          

          这些模式查找"'不跟随的空格和制表符(至少一个)。这是为了避免删除 html 属性之间的空格

          【讨论】:

            【解决方案14】:

            这对我有用,并且很容易添加/删除特殊情况。适用于 CSS、HTML 和 JS。

            function inline_trim($t)
            {
                $t = preg_replace('/>\s*\n\s*</', '><', $t); // line break between tags
                $t = preg_replace('/\n/', ' ', $t); // line break to space
                $t = preg_replace('/(.)\s+(.)/', '$1 $2', $t); // spaces between letters
                $t = preg_replace("/;\s*(.)/", ';$1', $t); // colon and letter
                $t = preg_replace("/>\s*(.)/", '>$1', $t); // tag and letter
                $t = preg_replace("/(.)\s*</", '$1<', $t); // letter and tag
                $t = preg_replace("/;\s*</", '<', $t); // colon and tag
                $t = preg_replace("/;\s*}/", '}', $t); // colon and curly brace
                $t = preg_replace("/(.)\s*}/", '$1}', $t); // letter and curly brace
                $t = preg_replace("/(.)\s*{/", '$1{', $t); // letter and curly brace
                $t = preg_replace("/{\s*{/", '{{', $t); // curly brace and curly brace
                $t = preg_replace("/}\s*}/", '}}', $t); // curly brace and curly brace
                $t = preg_replace("/{\s*([\w|.|\$])/", '{$1', $t); // curly brace and letter
                $t = preg_replace("/}\s*([\w|.|\$])/", '}$1', $t); // curly brace and letter
                $t = preg_replace("/\+\s+\'/", "+ '", $t); // plus and quote
                $t = preg_replace('/\+\s+\"/', '+ "', $t); // plus and double quote
                $t = preg_replace("/\'\s+\+/", "' +", $t); // quote and plus
                $t = preg_replace('/\"\s+\+/', '" +', $t); // double quote and plus
            
                return $t;
            }
            

            【讨论】:

              【解决方案15】:

              如果您有 8 位 ASCII,将删除它们并将字符保持在 128-255 范围内

               $text = preg_replace('/[\x00-\x1F\xFF]/', " ", $text );
              

              如果你有一个 UTF-8 编码的字符串就可以了

              $text = preg_replace('/[\x00-\x1F\x7F]/u', '', $text);
              

              了解更多信息 你有这个链接 more information

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-07-07
                • 1970-01-01
                • 1970-01-01
                • 2012-05-21
                • 2021-11-13
                • 2011-05-30
                • 1970-01-01
                相关资源
                最近更新 更多