【问题标题】:Regular expression to remove empty <span> tags删除空 <span> 标签的正则表达式
【发布时间】:2008-11-15 13:07:23
【问题描述】:

我想删除这样的空跨度标签(用&amp;nbsp; 和空格填充):

&lt;span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;

我已经尝试过这个正则表达式,但它需要调整:

(&lt;span&gt;(&amp;nbsp;|\s)*&lt;/span&gt;)

preg_replace('#&lt;span&gt;(&amp;nbsp;|\s)*&lt;/span&gt;#si','&lt;\\1&gt;',$encoded);

【问题讨论】:

  • 您需要先对 span 标签的内容进行 URL 解码,然后您的正则表达式才能处理您上面提供的示例。
  • 你的正则表达式没问题。只需将替换字符串从'&lt;\\1&gt;' 更改为''

标签: php html regex


【解决方案1】:

将 Kent Fredric 的正则表达式翻译成 PHP:

preg_match_all('#<span[^>]*(?:/>|>(?:\s|&nbsp;)*</span>)#im', $html, $result);

这将匹配:

  • 自动关闭跨度
  • 跨越多行和任何情况
  • 带属性的跨度
  • 跨越牢不可破的空间

也许您也应该包含仅包含 &lt;br /&gt; 的跨度...

像往常一样,在调整正则表达式时,有些工具很方便:

http://regex.larsolavtorvik.com/

【讨论】:

  • OP 希望空的 SPAN 元素删除
【解决方案2】:

.

qr{<span[^>]*(/>|>\s*?</span>)}

应该了解其中的要点。 (包括 XML style-self 结束标签,即:)

但是您真的不应该使用正则表达式进行 HTML 处理。

仅回答与纠正格式错误之前可见的问题上下文相关的问题

【讨论】:

  • 是的,我不能被需要的讨厌的引用样式塞满:/用户练习使正则表达式适合他们的语言:p
  • 我真的厌倦了人们说你不应该在任何类型的 XML 或 HTML 上使用正则表达式。有时使用 Beautiful Soup 之类的东西真的不合适
  • 在这种情况下,只要它从不在引用区域内发生就可以了。这使得它非常脆弱,我不会使用它,除非在紧要关头。
  • @nickf:它解决了数以百万计的新手的问题,他们将其用作第一个停靠港,然后自己进行 XSS 攻击。
【解决方案3】:

我想这些跨度是由某些程序生成的,因为它们似乎没有任何属性。
我很困惑为什么您需要将它们括起来的空格放在尖括号之间,但是我又不知道代码的最终目的。
我认为 Kent 给出了解决方案:您必须使匹配不贪婪:由于您使用 dotall 选项,您将匹配第一个跨度和最后一个关闭跨度之间的所有内容!

所以答案应该是这样的:

preg_replace('#&lt;span&gt;(&amp;nbsp;|\s)*?&lt;/span&gt;#si', '&lt;$1&gt;', $encoded);

(未经测试)

【讨论】:

    【解决方案4】:

    我已经尝试过这个正则表达式,但它需要调整:

    原始问题中的正则表达式以什么方式失败?

    问题来了,当跨度得到 嵌套喜欢:&lt;span&gt;&lt;span&gt; &amp;nbsp; &lt;/span&gt;&lt;/span&gt;

    这是为什么使用正则表达式解析 HTML 不能很好地工作的一个例子。根据您的正则表达式风格,这种情况要么不可能一次性处理,要么非常困难。我不太了解 PHP 的正则表达式引擎,无法说出它属于哪个类别,但是,如果唯一的问题是它取出了内部 &lt;span&gt; 并单独留下了外部,那么您可能需要考虑简单地重新重复运行你的替换,直到它没有事情可做。

    【讨论】:

    • 是的,我同意,但我想知道是否有办法递归地重新运行它?否则很难预测嵌套标签的编号/名称...
    【解决方案5】:

    如果您唯一的问题是嵌套跨度标签,您可以使用循环中的正则表达式运行搜索和替换,直到正则表达式不再找到任何匹配项。

    这可能不是一个非常优雅的解决方案,但它会表现得足够好。

    【讨论】:

      【解决方案6】:

      这是我对嵌套标签问题的解决方案,仍然不完整但接近...

      $test="<span>   <span>& nbsp;  </span>  test <span>& nbsp; <span>& nbsp;  </span>  </span> & nbsp;& nbsp; </span>";
      
      $pattern = '#<(\w+)[^>]*>(& nbsp;|\s)*</\1>#im';      
      while(preg_match($pattern, $test, $matches, PREG_OFFSET_CAPTURE)!= 0)
      {$test= preg_replace($pattern,'', $test);}
      

      对于简短的 $test 句子,该功能可以正常工作。尝试使用长文本时会出现问题。任何帮助将不胜感激...

      【讨论】:

        【解决方案7】:

        稍微修改一下e-satis的回答:

        function remove_empty_spans($html_replace)
        {
        $pattern = '/<span[^>]*(?:\/>|>(?:\s|&nbsp;)*<\/span>)/im';
        return preg_replace($pattern, '', $html_replace);
        }
        

        这对我有用。

        【讨论】:

          猜你喜欢
          • 2015-06-18
          • 1970-01-01
          • 2011-05-15
          • 1970-01-01
          • 2011-04-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多