【问题标题】:Can I safely replace "<ul>" tags within HTML using regexes?我可以使用正则表达式安全地替换 HTML 中的“<ul>”标签吗?
【发布时间】:2021-10-09 23:35:59
【问题描述】:

我正在尝试解决this issue 的问题,其中用户粘贴了我们必须处理的无效 HTML,格式为 &lt;ol&gt;&lt;ul&gt;&lt;li&gt;item&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;。我们目前正在使用lxml 进行解析。在合法的 HTML 中,&lt;ol&gt; 不能有 &lt;ul&gt; 的(直接)子代(它必须在 &lt;li&gt; 中),因此 lxml 过早关闭 ol 标记以尝试“修复”HTML,产生&lt;div&gt;&lt;ol/&gt;&lt;ul&gt;&lt;li&gt;item&lt;/li&gt;&lt;/ul&gt;

用户粘贴的文本也可能是无效的 XML(例如,裸 &lt;br&gt; 标记),因此我们不能将其解析为 XML。

因此,我们既不能将其解析为 HTML 也不能解析为 XML,因为它可能是无效的。

为了使这种无效 HTML 的特定(常见)情况变为有效 HTML,我们可以使用正则表达式将所有 &lt;ul&gt; 标记替换为 &lt;ol&gt; 标记吗?

如果我使用 lxml 解析 &lt;ol&gt;&lt;ol&gt;&lt;li&gt;item&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;,输出看起来很好(不会过早关闭标签)。

但是,我不想破坏实际的用户键入的文本,我想知道是否存在我没​​有想到的边缘情况(例如 &lt;pre&gt; 标记或其他一些中的“&lt;ul&gt;”疯狂的东西实际上不是标签,尽管我已经测试过那个特殊情况)。

是的,它会将未编号列表更改为编号列表。我没关系。

是的,我已经阅读了this fun regex answer

【问题讨论】:

  • 出于同样的原因,您不能将 &lt;ol&gt; 作为 &lt;ol&gt; 的直接子代。
  • 垃圾进,垃圾出。浏览器在收到无效的 HTML 时会做类似的事情。
  • 除非您知道人们会粘贴的所有类型的错误 HTML,否则您将无法以通用、稳健的方式解决此问题。 lxml 已经在尽最大努力解决错误,是什么让您认为您的修复会更好?
  • 为了清楚起见,&lt;ol&gt;&lt;ol&gt;&lt;li&gt;item&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;“看起来不错”= 不受影响/嵌套 ol 输出 (??),而&lt;ol&gt;&lt;ul&gt;&lt;li&gt;item&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;“关闭 ul 之前的第一个 ol”?还是我看错了..
  • 无论如何,在某些情况下,直接替换可能会无效改变 HTML - HTML cmets 内部、脚本元素内部、属性值内部。可能有更多的上下文。

标签: html regex lxml


【解决方案1】:

通常,不能保证使用 HTML 和正则表达式进行“非边缘情况”转换。 HTML 比 XML 更具有规则,可以直接用文本替换看起来像标签的东西有问题。

以下文字validates as HTML using w3c.org validation checker没有任何警告。

<!DOCTYPE html>
<html lang="en">
<head>
  <title><!--<ul>--></title>
  <style lang="css">s {content: "<ul>";}</style>
  <script>"<ul>"</script>
</head>
<body data-ul="<ul>"></body>
</html>

除此之外,使用一些正则表达式启发式可能会解决手头的问题 - 至少在合理范围内。不尝试应用任何验证或 DOM/树构建的流式 HTML 令牌解析器也可能对初始替换阶段有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-05
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2018-08-11
    • 2011-11-20
    相关资源
    最近更新 更多