【问题标题】:Compress whitespace between attributes in an HTML tag压缩 HTML 标记中属性之间的空格
【发布时间】:2010-12-07 18:25:15
【问题描述】:

我们刚刚发布了一些代码以使我们的软件更加用户友好,但结果适得其反。基本上,我们试图用<br /> 标签替换换行符。问题是,有时我们的用户会输入如下代码:

<a
 href='http://nowhere.com'>Nowhere</a>

当我们运行我们的代码时,这会转化为

<a <br />href='http://nowhere.com' />Nowhere</a>

这显然不能正确渲染。

是否有正则表达式或 PHP 函数可以去除或压缩 HTML 标记属性之间的空白?

澄清:这不是完整的 HTML。它更类似于 Markdown 或其他一些语言(我们最终将转向 Markdown,但我需要快速修复)。所以我不能把它解析为普通的 HTML。换行符需要正确转换为&lt;br /&gt;标签。

【问题讨论】:

  • @ajreal - trim() 只会做字符串的开头和结尾。

标签: php attributes newline whitespace


【解决方案1】:

嗯,你为什么要使用格式化 html 的工具而不是为此目的而设计的,给你自己一个 DOM 库。

http://simplehtmldom.sourceforge.net/

【讨论】:

  • 我正在解析的不是有效的 HTML,它是其中可能包含 HTML 的文本。因此,HTML 的部分需要是有效的,但其余的只是文本。
  • 那么你有没有实现&lt;br /&gt;标签的原始内容?如果是这样,将其放入 DOM Parser,循环抛出每个元素并将属性放置在一个新的新标签中,然后将其格式化。
  • 我不确定我是否遵循。如果我将文本放入 DOM 解析器,我会丢失所有需要转换为 &lt;br /&gt; 标签的换行符,对吧?
  • 您上面的文本是您翻译的文本以换行以正确打破标签,所以如果您有 html 版本(带有换行符)然后将该 html 放入 DOM 解析器,循环抛出它找到的每个元素并提取每个标签及其属性/值并插入到由 DOM 解析器创建的新元素中,一旦 DOMparser 研究了整个文档,它们将其输出为 html,您应该有一个干净的文档。为什么无论如何都需要替换新行新行,网页设计中没有使用过什么,所以你不需要用&lt;br /&gt;替换它们
  • 这些是电子邮件模板和用户签名,所以大多数时候它们只有文本。文本需要转换为 HTML 以显示在电子邮件消息中,并使用用户请求的换行符进行格式化。此外,这些模板有时需要包含返回站点的链接的基本 HTML。由于整个正文不是真正的 HTML,我不能使用 DOM 解析器。我找到了一个我会尽快添加的解决方案。
【解决方案2】:

你需要一个能正确解析你扔给它的所有 HTML 的库,你永远不知道用户会发明什么。

看HTML Purifier

【讨论】:

    【解决方案3】:

    经过一番搜索和反复试验,我想出了以下解决方案/hack:

    /*
     * Compress all whitespace within HTML tags (including PRE at the moment)
     */
    $regexp = "/<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/i";
    
    preg_match_all($regexp, $text, $matches);
    
    foreach($matches[0] as $match) {
      $new_html = preg_replace('/\s+/', ' ', $match);
      $text = str_replace($match, $new_html, $text);
    }
    

    执行此代码后,$text 中的所有 HTML 标记都将正确格式化并有效,不包含换行符。

    我知道这不是最好的解决方案,但它确实有效,而且很快我们就会迁移到真正的标记语言(例如 Markdown)。

    【讨论】:

    • 我对其他有帮助的答案投了赞成票,但决定接受我自己的答案,因为这是我针对这个特定问题的实际解决方案。
    【解决方案4】:

    理想情况下,您会通过 DOM 或 SAX API 使用 XML 解析器。但是,如果您的内容不是正确的 XML,而是带有一些标签的纯文本,则解析器可能会失败(我猜这取决于使用的工具)。

    针对您的特定问题的粗略解决方案可能如下:构造一个具有两种状态的状态机,标签内和标签外。您逐个字符地读取输入。读取“”后,切换到“外部”状态。读取 '\n' 并且如果处于“外部”状态,则发出“
    ”(否则不发出任何内容)。

    这只是一个草图,可能需要完善。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多