问题描述
我正在使用python中的正则表达式寻求帮助,而google却使我失望。 基本上,我正在搜索一些html,并且正在搜索某种类型的表,尤其是其中包含背景标签(即BGCOLOR)的任何表。 有些表带有此标记,有些则没有。 有人可以帮助我解决如何编写一个正则表达式来搜索表的开头,然后搜索BGCOLOR,但是如果它到达表的末尾,它将停止并继续前进吗?
这是一个非常简单的示例,将达到目的:
`<TABLE>
<B>Item 1.</B>
</TABLE>
<TABLE>
BGCOLOR
</TABLE>
<TABLE>
<B>Item 2.</B>
</TABLE>`
因此,我们有三个表,但我只想查找包含“ BGCOLOR”的中间表。目前,我的正则表达式存在的问题是它会搜索起始表标记,然后查找“ BGCOLOR”,并且不在乎它通过表结束标记:
tables = re.findall('\<table.*?BGCOLOR=".*?".*?\<\/table\>', text, re.I|re.S)
因此它将找到前两个表,而不仅仅是第二个表。 让我知道是否有人知道如何处理这种情况。
谢谢迈克尔
1楼
不要使用正则表达式来解析HTML。 使用或 。
2楼
不要使用正则表达式来解析HTML,而应使用HTML解析器,例如 。
具体来说,您的情况基本上是必须处理“嵌套括号”(打开的“ parens”是开始的<table>
标记,而对应的闭合的parens是匹配的</table>
)之一-正是这种解析的形式正则表达式不能很好执行的任务。
解析HTML的许多工作都与“匹配括号”问题完全相关,这使正则表达式成为达到此目的的完美选择。
您在对另一个答案的评论中提到您在BS中遇到了未指定的问题-我怀疑您正在尝试的是最新的3.1版本(已经下坡了),而不是正确的版本。 如推荐,尝试3.0.8,这样可能会更好。
如果您与Evil达成某种协议,从不使用正确的工具来完成工作,那么,如果您不需要处理嵌套 (只是匹配),那么您的任务可能就不会完全不可能,例如,永远不会有表格在另一个桌子里面。
在这种情况下,您可以使用r'<\\s*TABLE(.*?)<\\s*/\\s*TABLE'
(带有适当的标志,例如re.DOTALL
和re.I
)来标识一个表;
使用正则表达式的方法遍历所有此类匹配项;
并在循环的主体中检查BGCOLOR
(不区分大小写)是否恰好在当前匹配的主体内。
与使用HTML解析器相比,它仍将更加脆弱,而且工作量也更多,但是尽管绝对是次等选择,但这并不一定是一个绝望的情况。
如果确实有嵌套表要应对,那就是一种绝望的情况。
3楼
如果您的任务就是这么简单,这是一种方法。
在<TABLE>
上分割,然后迭代各项并找到所需的所需模式。
myhtml="""
<TABLE>
<B>Item 1.</B>
</TABLE>
some text1
some text2
some text3
<TABLE>
blah
BGCOLOR
blah
</TABLE>
some texet
<TABLE>
<B>Item 2.</B>
</TABLE>
"""
for tab in myhtml.split("</TABLE>"):
if "<TABLE>" in tab and "BGCOLOR" in tab:
print ''.join(tab.split("<TABLE>")[1:])
输出
$ ./python.py
blah
BGCOLOR
blah
4楼
这是最终为我工作的代码。 它找到正确的表并在其周围添加更多标签,以便使用“ realTable”的打开和关闭标签从该组中进行识别。
soup = BeautifulSoup(''.join(text))
for p in soup.findAll('table'):
pattern = '.*BGCOLOR.*'
if (re.match(pattern, str(p), re.S|re.I)):
tags = Tag(soup, "realTable")
p.replaceWith(tags)
text = NavigableString(str(p))
tags.insert(0, text)
print soup
打印出来:
<table><b>Item 1.</b></table>
<realTable><table>blah BGCOLOR blah</table></realTable>
<table><b>Item 2.</b></table>