需要Python正则表达式帮助

时间:2010-08-01 15:25:04

标签: python regex

我需要从一个网站上获取信息,该网站随机地在<font color="red">needed-info-here</font><span style="font-weight:bold;">needed-info-here</span>之间输出。

当我使用

时,我可以得到它
start = '<font color="red">'
end = '</font>'
expression = start + '(.*?)' + end
match = re.compile(expression).search(web_source_code)
needed_info = match.group(1)

,但是当网站使用其他标记时,我必须选择提取<font><span>,失败。

如何修改正则表达式以便它始终成功?

6 个答案:

答案 0 :(得分:7)

Don't parse HTML with regex.

正则表达式不适合用于解决此问题。查看BeautifulSouplxml

答案 1 :(得分:3)

您可以使用竖线连接两个选项:

start = '<font color="red">|<span style="font-weight:bold;">'
end = '</font>|</span>'

因为您知道字体标记始终由</font>关闭,所以范围标记始终为</span>

但是,考虑使用一个可靠的HTML解析器(如BeautifulSoup),而不是滚动自己的正则表达式来解析HTML,这通常不适合通过正则表达式进行解析。

答案 2 :(得分:1)

虽然正则表达式是解析HTML的最佳选择。

为了教育,这里可以回答你的问题:

start = '<(?P<tag>font|tag) color="red">'
end = '</(?P=tag)>'
expression = start + '(.*?)' + end

答案 3 :(得分:1)

expression = '(<font color="red">(.*?)</font>|<span style="font-weight:bold;">(.*?)</span>)'
match = re.compile(expression).search(web_source_code)
needed_info = match.group(2)

这可以完成工作,但你不应该真正使用正则表达式来解析html

答案 4 :(得分:1)

正则表达式和HTML并不是一个很好的匹配,HTML有太多潜在的变化会使你的正则表达式绊倒。 BeautifulSoup是这里使用的标准工具,但我发现在尝试相对于特定的先前标记定位特定标记时,pyparsing可以同样有效,有时甚至更简单。

以下是使用pyparsing解决问题的方法:

html = """ need to get info from a website that outputs it between <font color="red">needed-info-here</font> OR <span style="font-weight:bold;">needed-info-here</span>, randomly.
<font color="white">but not this info</font> and 
<span style="font-weight:normal;">dont want this either</span>
"""

from pyparsing import *

font,fontEnd = makeHTMLTags("FONT")
# only match <font> tags with color="red"
font.setParseAction(withAttribute(color="red"))
# only match <span> tags with given style
span,spanEnd = makeHTMLTags("SPAN")
span.setParseAction(withAttribute(style="font-weight:bold;"))

# define full match patterns, define "body" results name for easy access
fontpattern = font + SkipTo(fontEnd)("body") + fontEnd
spanpattern = span + SkipTo(spanEnd)("body") + spanEnd

# now create a single pattern, matching either of the other patterns
searchpattern = fontpattern | spanpattern

# call searchString, and extract body element from each match
for text in searchpattern.searchString(html):
    print text.body

打印:

needed-info-here
needed-info-here

答案 5 :(得分:0)

我没有使用过Python,但如果你使表达式等于以下内容,它应该可以工作:

/(?P<open><(font|span)[^>]*>)(?P<info>[^<]+)(?P<close><\/(font|span)>)/gi

然后只需使用“info”这个名称访问您需要的信息。

PS - 我也同意“不用正则表达式解析HTML”规则,但如果你知道它会出现在font或span标签中,那么就这样吧......

另外,为什么要使用字体标签?自从我学习CSS以来,我没有使用过字体标记。