我正在寻找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)
所以它会找到前两个表而不是第二个表。如果有人知道如何处理这种情况,请告诉我。
谢谢, 迈克尔
答案 0 :(得分:4)
不要使用正则表达式来解析HTML。使用lxml
或BeautifulSoup
。
答案 1 :(得分:3)
不要使用正则表达式来解析HTML - 使用HTML解析器,例如BeautifulSoup。
具体来说,你的情况基本上是必须处理“嵌套括号”(其中一个开放的“parens”是一个开放的<table>
标签,相应的封闭的parens是匹配的</table>
) - - 正是那种正则表达式无法很好地执行的解析任务。解析HTML的许多工作与这个“匹配的括号”问题完全相关,这使得正则表达式成为一个非常可怕的选择。
你在另一个答案的评论中提到你有一个未指明的BS问题 - 我怀疑你正在尝试最新的3.1版本(已经走下坡路)而不是正确的版本;尝试3.0.8而不是BS's own docs推荐,你可能会更好。
如果您与Evil达成某种协议,永远不会使用正确的工具来完成工作,如果您不需要处理嵌套,那么您的任务可能并非完全不可能匹配),即在另一个表中永远不存在表。在这种情况下,您可以使用r'<\s*TABLE(.*?)<\s*/\s*TABLE'
标识一个表(包含re.DOTALL
和re.I
等合适的标记;使用正则表达式的finditer
方法循环所有此类匹配;并在循环体中检查BGCOLOR
(在不区分大小写的意义上)是否恰好位于当前匹配的主体内。它仍然比使用HTML解析器更脆弱,更多的工作,但绝对是一个低劣的选择,它不一定是绝望的情况。
如果你做有嵌套表来竞争,那么 就是绝望的情况。
答案 2 :(得分:0)
如果你的任务就是这么简单,这就是一种方式。拆分<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
答案 3 :(得分:0)
这是最终为我工作的代码。它找到了正确的表并在其周围添加了更多标记,以便从组中使用'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>