【问题标题】:Regex to match attributes in HTML?正则表达式匹配 HTML 中的属性?
【发布时间】:2009-01-21 11:30:25
【问题描述】:

我有一个 txt 文件,它实际上是某个网页的 html 源。 在该 txt 文件中,有各种以“title=”标记开头的字符串。 例如

<div id='UWTDivDomains_5_6_2_2'  title='Connectivity Framework'> 

我有兴趣提取文本 Connectivity Framework 并将其写入单独的文件。

像这样,有很多这样的标签,每个标签在 title='some text here which I need to extract' 之后都有不同的文本 我想从 html 源/txt 文件中提取所有此类文本实例并写入单独的 txt 文件。文本只能包含小写、大写字母和数字。每个文本字符串的长度(以字符为单位)会有所不同。

我正在为 Windows 使用 PowerGrep。 Powergrep 允许我使用正则表达式 inout 搜索文本文件。 我尝试使用搜索作为 标题='[a-zA-Z0-9]

它显示正确的匹配,但它只匹配字符串的第一个字符,并且只写入与第二个 txt 文件匹配的文本字符串的第一个字符,而不是所有字符串。

我希望所有字符串都匹配并写入第二个文件。

什么是正确的正则表达式或使用 powergrep 做我想做的事情的方法?

-AD。

【问题讨论】:

    标签: html regex parsing


    【解决方案1】:

    我只是不确定必须询问多少次 HTML 文件的正则表达式解析问题(并以“使用 DOM 解析器”的正确解决方案来回答)。它每天都会出现。

    困难在于:

    • 在 HTML 中属性可以有单引号、双引号甚至没有引号;
    • 类似的字符串可以出现在 HTML 文档本身中;
    • 您必须处理正确的转义;和
    • HTML 格式错误(体面的解析器对常见错误非常稳健)。

    因此,如果您满足所有这些要求(它会变得非常复杂但仍然不完美),它仍然不是 100%。

    HTML 解析器的存在是有原因的。使用它们。

    【讨论】:

    • 我相信曾经有一个标签,但我想有人去把它从所有东西中删除了。它相当令人沮丧的是这种频率出现的频率。黏? :P
    • 我们确实需要一些东西来阻止这个问题每天出现多次。某种弹出提问者的常见问题解答将“正则表达式”和“html”标签一起使用?
    • 有时需要快速“解析”/检查 html。 DOM-Parser 的内存和速度都很重。因此,如果我必须处理大量数据,则正则表达式更容易、更快。当然有一些限制。
    • 这就是 SAX 解析器的用途。
    【解决方案2】:

    其他答案都对正则表达式进行了正确的更改,因此我将解释您的原始答案存在什么问题。

    方括号表示character class - 表示正则表达式将匹配这些括号内的任何字符。但是,与其他所有内容一样,默认情况下它只会匹配一次。正如正则表达式“s”将仅匹配“ssss”中的第一个字符一样,正则表达式“[a-zA-Z0-9]”将仅匹配“Connectivity Framework”中的第一个字符。

    通过添加repetition,可以使该字符类重复匹配。最简单的方法是在它之后添加一个星号(它将匹配 0 次或更多次出现)。因此,正则表达式 "[a-zA-Z0-9]*" 将匹配一行中的尽可能多的字符,直到它遇到不在该字符类中的字符(在您的情况下,空格字符,因为您没有在括号中包含它)。

    虽然正则表达式很难准确地描述语法 - 如果有人在属性中放置非字母数字字符(例如&符号)怎么办?您可以尝试通过将字符集设置为“除引号字符之外的任何内容”来捕获引号之间的所有输入,因此“'[^']*'”通常会做正确的事情。通常您还需要记住转义(例如,使用字符串 'Mary\'s lamb' 您确实想要捕获中间的撇号,因此简单的“除了撇号”字符集不会削减它)虽然谢天谢地这不是根据规范,XML/HTML 存在问题。

    不过,如果有一个现有的库可以为您进行提取,这可能比滚动您自己的库更快、更正确,所以如果可能的话,我会倾向于这样做。

    【讨论】:

      【解决方案3】:

      我不熟悉 PowerGrep,但是,您的正则表达式不完整。试试这个:

      title='[a-zA-Z0-9 ]*'
      

      或者更好:

      title='([^']*)'
      

      【讨论】:

      • 对不起,但这仍然不能完成工作。更多字符对属性有效,您想要解码的实体也是如此,您的示例现在使用单引号而不是双引号。一个有效的正则表达式应该与一对匹配的单引号或双引号一起工作。
      • 我同意您可以使用更复杂的正则表达式。例如,您可以对开头的引号 - (['"]) 进行分组,并在引号之间和结尾处使用反向引用。我故意避免过度复杂化,怀疑提问者对正则表达式并不满意。
      【解决方案4】:

      我会使用这个正则表达式来获取标题属性值

      <[a-z]+[^>]*\s+title\s*=\s*("[^"]*"|'[^']*'|[^\s >]*)
      

      请注意,此正则表达式匹配带引号的属性值表达式。因此,如果需要,您必须删除它们。

      【讨论】:

        【解决方案5】:

        这是您需要的正则表达式

        title='([a-zA-Z0-9]+)'
        

        但如果您要做更多这样的事情,使用解析器可能会使其更加健壮和有用。

        【讨论】:

          【解决方案6】:

          试试这个:

          title=\'[a-zA-Z0-9]*\'
          

          【讨论】:

            猜你喜欢
            • 2010-11-24
            • 1970-01-01
            • 1970-01-01
            • 2011-09-03
            • 1970-01-01
            • 1970-01-01
            • 2011-12-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多