【问题标题】:Is ">" (U+003E GREATER-THAN SIGN) allowed inside an html-element attribute value?html元素属性值中是否允许“>”(U+003E GREATER-THAN SIGN)?
【发布时间】:2010-09-12 23:12:56
【问题描述】:

换句话说,可以使用/<tag[^>]*>.*?<\/tag>/ 正则表达式来匹配不包含嵌套tag 元素的tag html 元素吗?

例如(lt.html):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>greater than sign in attribute value</title>
  </head>
  <body>
    <div>1</div>
    <div title=">">2</div>
  </body>
</html>

正则表达式:

$ perl -nE"say $1 if m~<div[^>]*>(.*?)</div>~" lt.html

还有屏幕刮板:

#!/usr/bin/env python
import sys
import BeautifulSoup

soup = BeautifulSoup.BeautifulSoup(sys.stdin)
for div in soup.findAll('div'):
    print div.string


$ python lt.py <lt.html

两者都给出相同的输出:

1
">2

预期输出:

1
2

w3c 说:

属性值是文本的混合 和字符引用,除了 附加限制 文本不能包含歧义 和号。

【问题讨论】:

  • 这是大家用来解释为什么不应该使用正则表达式解析HTML的教科书示例,而应该使用HTML Parser。

标签: html regex syntax


【解决方案1】:

是的,它是允许的(W3C Validator 接受它,只发出警告)。

在 cmets 中也允许未转义的 &lt;&gt;,所以这样简单的正则表达式可以被愚弄。

如果 BeautifulSoup 没有处理这个问题,这可能是一个错误,或者可能是一个有意识的设计决定,以使其对缺少属性中的右引号更具弹性。

【讨论】:

    【解决方案2】:

    文字 &gt; 在 html 内容中的任何地方都是合法的,无论是在属性值内部还是作为元素内的文本。

    【讨论】:

      【解决方案3】:

      我认为这是有效的,W3C 验证者也同意,但此信息的权威来源是 ISO 8879:1986 标准,成本约为 150 欧元/210 美元。无论如何,编码它们并没有错,所以如果有疑问,编码。此外,如果您使用的是基于 XML 的文档类型,则需要在序列]]&gt; 中编码大于号。

      【讨论】:

        【解决方案4】:

        阅读以下内容后:

        http://www.w3.org/International/questions/qa-escapes

        似乎在 和 &

        的任何地方(包括属性中)都建议使用实体转义

        【讨论】:

        • 那个文件是错误的。内容中的裸大于号是有效的。它还说单个 & 符号是错误的,但 HTML 并非总是如此。
        • 它并没有说大于号是无效的,它只是建议使用实体来代替——只有傻瓜才会忽略的建议,IMO。谁在乎它是否有效,如果大多数程序员(包括许多软件工具的作者)认为它不是有效的?
        【解决方案5】:

        如果您坚持使用正则表达式(适用于基本字符串操作),请尝试使用&lt;tag((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'"&gt;\s]+))?)+\s*|\s*)&gt;.*?&lt;\/tag&gt;。它应该完美匹配属性,因此允许您访问内部内容(尽管您需要将其放在捕获组中)。

        您也可以使用Html Agility Pack 来解析 HTML,如果您要进行大量解析,我建议您使用它。维护大型正则表达式很容易让人头疼,但与此同时,如果您能够这样做,它们也会更有效。

        【讨论】:

          【解决方案6】:
          yeah except /<tag[^>]*>.*?<\/tag>/
          

          不会匹配单个标签,而是匹配给定标签的第一个开始标签和最后一个结束标签。就像你的第一个非贪婪标签匹配一样,你的中间也应该写成非贪婪的。

          【讨论】:

          • 我不明白。你能举个例子吗?
          • @jf-sebastian:
            flo
            bar
            你匹配第一个
          【解决方案7】:

          查看使用 > 是否得到相同的结果而不是 >

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-02-22
            • 2010-10-01
            • 2011-08-18
            • 2011-04-29
            • 1970-01-01
            相关资源
            最近更新 更多