【问题标题】:Extract the text from <b></b> tags从 <b></b> 标签中提取文本
【发布时间】:2012-05-05 02:06:46
【问题描述】:

我有文本(Python 2.6 的代码):

txt="foo<br><br><b>bar :</b><br>foo<br><b>bar :</b>"

然后我尝试提取任意标签(本例中为标签)的内容:

r=re.compile("<%s.*?>(.+?)</%s>" % ("b","b"), re.I|re.S)

这主要是可行的,但输出不是我对我的棘手文本的预期:

>>>re.findall(r,txt)
['<br><b>bar :', 'foo<br><b>bar :']

在任何情况下都可以编写一个正则表达式来从任何 HTML 标记中提取文本吗?

【问题讨论】:

  • 为此目的使用 html 解析器,例如 Beautiful Souplxml
  • 您的要求不够明确。我推断如果嵌套将是非法的,并且假设结束标记会修复它,我推断你想假设一个结束 b 标记?这远远超出了正则表达式的合理使用。您需要一个健壮的 HTML 标签解析器。幸运的是,其中有很多。
  • @KurzedMetal:使用 BeautifulSoup 而不是 lxml 的任何具体原因。
  • @RanRag:有什么理由编辑评论吗?我只是给了 OP 我想到的第一个选项。
  • @RanRag anything 比正则表达式更好地解析 html。 :P 我实际上发现 lxml 对使用 xpath 和 beautifulsoup 进行解析以遍历网页很有用。

标签: python html regex tags


【解决方案1】:

我不完全确定您要做什么,但我认为这个正则表达式可以满足您的要求:

>>> re.findall(re.compile(r"<(\w+)>(.+?)</\1>", re.I|re.S), "foo<br><br><b>bar :</b><br>foo<br><b>bar :</b>")
[('b', 'bar :'), ('b', 'bar :')]

【讨论】:

    【解决方案2】:
    (?<=<b>).*?(?=<\/b>)
    

    此正则表达式模式将获取标签内的所有文本。

    http://regexr.com?30oga

    【讨论】:

    • 是的!谢谢!这正是我一直在寻找的!我想出了: re.compile("\n]).*?>(.+?)%s>" % ("b","b"), re.I|re.S) 基本上是相同的想法。
    • NP,如果你喜欢,请点击我的答案旁边的复选标记。
    【解决方案3】:

    一般来说,您不能使用正则表达式解析 HTML,因为正则表达式只能捕获正则表达式语言。 HTML 语言包含任意嵌套,而正则表达式无法处理这些。

    也就是说,您可以提取典型 html 的打开和关闭标签之间的文本,只要您对正则表达式代码进行一点小改动:

    r=re.compile("<%s.*?>(.+?)</%s>" % ("b","b"), re.I|re.S) 
    


    >>> r=re.compile("<%s>(.+?)</%s>" % ("b","b"), re.I|re.S)
    >>> txt="foo<br><br><b>bar :</b><br>foo<br><b>bar :</b>"
    >>> re.findall(r, txt)
    ['bar :', 'bar :']
    

    .*?允许
    匹配您的开始标签。

    但是,此策略仅将与您的模式匹配的第一个标签与与您的模式匹配的 first 结束标签匹配,而不是与实际与打开标签配对的标签匹配。当嵌套相同的标签时,它不会像您期望的那样做,如下例所示:

    >>> txt="foo<b><b><b>bar :</b></b></b><br>foo<br><b>bar :</b>"
    >>> re.findall(r, txt)
    ['<b><b>bar :', 'bar :']
    >>> 
    

    【讨论】:

    • 我对答案的 +1。这与语言理论有关。嵌套结构不能被正则表达式解析。扩展的正则表达式实际上更强大一些。尽管如此,使用一个像样的解析器总是更好。
    【解决方案4】:

    正如其他人指出的那样,使用正则表达式解析 HTML 通常不是一个好主意。我建议你使用htmllib。例如:

    import htmllib
    
    class MyParser(htmllib.HTMLParser):     
      def __init__(self, fmt):
        htmllib.HTMLParser.__init__(self, fmt)        
        self.inb = False
    
      def start_b(self, data):
        self.inb = True
    
      def end_b(self):
        self.inb = False
    
      def handle_data(self, data):
        if self.inb: 
           #do sth with data
    

    【讨论】:

    【解决方案5】:

    或 BeautifulSoup(非常快):

    from bs4 import BeautifulSoup as soup
    
    txt="foo<br><br><b>bar :</b><br>foo<br><b>bar :</b>"
    your_text = soup(txt)
    for your in your_text:
        your_text = your.findAll('b')
        print your_text.text
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      • 2023-03-12
      • 2021-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多