在Python中使用正则表达式匹配直到结束标签
我在用Python写正则表达式时遇到了一些问题,谷歌也没能帮我解决。简单来说,我在搜索一些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)
所以它会找到前两个表格,而不是只找到第二个表格。如果有人知道该怎么处理这种情况,请告诉我。
谢谢,
Michael
4 个回答
这是我最终用的代码。它能找到正确的表格,并在表格周围添加更多的标记,这样就能通过'真实表格'的开始和结束标签来识别它。
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>
不要用正则表达式来解析HTML,应该使用HTML解析器,比如BeautifulSoup。
具体来说,你的情况就像是要处理“嵌套的括号”(这里的开括号是打开的<table>
标签,而对应的闭括号是匹配的</table>
标签)——这正是正则表达式无法很好处理的解析任务。解析HTML时,很多工作都与这个“匹配括号”的问题有关,这使得正则表达式成为一个非常糟糕的选择。
你在对另一个答案的评论中提到你在使用BeautifulSoup时遇到了不明的问题——我怀疑你可能在尝试最新的3.1版本(这个版本表现不佳),而不是合适的版本;可以试试3.0.8版本,正如BeautifulSoup的官方文档推荐的那样,这样可能会更好。
如果你和“邪恶”达成了某种协议,决定不使用合适的工具来完成任务,那么如果你不需要处理嵌套(只需要匹配),也就是说,表格里从来没有另一个表格,那么你的任务可能并不是完全不可能。在这种情况下,你可以用r'<\s*TABLE(.*?)<\s*/\s*TABLE'
来识别一个表格(使用合适的标志,比如re.DOTALL
和re.I
);然后用正则表达式的finditer
方法循环遍历所有匹配项;在循环体内检查当前匹配的内容中是否包含BGCOLOR
(不区分大小写)。虽然这样做仍然会更脆弱,也需要更多的工作,但虽然是一个较差的选择,也不至于让人绝望。
如果你确实需要处理嵌套的表格,那么情况就非常糟糕了。
不要用普通的正则表达式来解析HTML。应该使用lxml
或者BeautifulSoup
这两个工具。