从<b> </b>标记中提取文本

时间:2012-04-24 12:32:34

标签: python html regex tags

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

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

然后我尝试提取任何标记的内容(在此示例中为&lt; b&gt;标记):

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

这大部分都有效,但输出并不是我对我棘手的文字所期望的:

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

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

5 个答案:

答案 0 :(得分:3)

通常,您无法使用正则表达式解析HTML,因为正则表达式仅捕获正则表达式语言。 HTML语言包含任意嵌套,正则表达式无法处理这些嵌套。

也就是说,如果你只对你的正则表达式代码做一个小改动,你可以在典型的html的open和close标签之间提取文本:

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

答案 1 :(得分: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

答案 2 :(得分: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 :')]

答案 3 :(得分:1)

(?<=<b>).*?(?=<\/b>)

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

http://regexr.com?30oga

答案 4 :(得分: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