1

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

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

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

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

这主要是有效的,但输出不是我对我的棘手文本所期望的:

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

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

4

5 回答 5

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 :']

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

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

>>> txt="foo<b><b><b>bar :</b></b></b><br>foo<br><b>bar :</b>"
>>> re.findall(r, txt)
['<b><b>bar :', 'bar :']
>>> 
于 2012-04-24T12:51:16.497 回答
2

正如其他人指出的那样,使用正则表达式解析 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
于 2012-04-24T13:00:20.550 回答
1
(?<=<b>).*?(?=<\/b>)

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

http://regexr.com?30oga

于 2012-04-24T12:50:47.780 回答
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 :')]
于 2012-04-24T12:47:29.603 回答
1

或 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
于 2012-04-24T13:16:35.710 回答