python re.findall没有找到所有

时间:2016-02-06 08:42:40

标签: python

content='<tr><td style="text-align:center;" height="30">12090043</td>'+\
        '<td style="text-align:left;">CourseA</td>'+\
        '<td style="text-align:center;">3</td>'+\
        '<td style="text-align:left;">86</td><td>2013-Summer</td></tr>'+\
        '<tr><td style="text-align:center;" height="30">10420844</td>'+\
        '<td style="text-align:left;">CourseB</td>'+\
        '<td style="text-align:center;">4</td>'+\
        '<td style="text-align:left;">98</td><td>2013-Autumn</td></tr>'
pattern=re.compile('<tr>.*"30">(.*)</td>.*"text-align:left;">(.*)</td>.*"text-align:center;">(.*)</td>.*"text-align:left;">(.*)</td><td>(.*)</td></tr>')
items=re.findall(pattern,content)
print items

输出结果为:

[('10420844', 'courseB', '4', '98', '2013-Autumn')]

但预期的结果是:

[('12090043', 'courseA', '3', '86', '2013-Summer'),('10420844', 'courseB', '4', '98', '2013-Autumn')]

实际上,如果有超过2个匹配项,此代码仅返回最后一个匹配项。谁能告诉我为什么会这样?对不起,长代码并提前致谢!

2 个答案:

答案 0 :(得分:2)

您可以使用BeautifulSoup执行此操作,如下所示:

import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

RegEx不是解析HTML的正确工具。不要试图调试你的代码,而是完全放弃它并使用像上面的例子一样的HTML解析器(BeautifulSoup)。

答案 1 :(得分:1)

以下是使用ElementTree的解决方案

content="""
    <tr><td style="text-align:center;" height="30">12090043</td>
    <td style="text-align:left;">CourseA</td>
    <td style="text-align:center;">3</td>
    <td style="text-align:left;">86</td><td>2013-Summer</td></tr>
    <tr><td style="text-align:center;" height="30">10420844</td>
    <td style="text-align:left;">CourseB</td>
    <td style="text-align:center;">4</td>
    <td style="text-align:left;">98</td><td>2013-Autumn</td></tr>
"""

import xml.etree.ElementTree as ET
root = ET.fromstring("<table>%s</table>"%content)
items = [tuple(col.text for col in row.findall("./td")) for row in root.findall("./tr")]

此处,将包含

[('12090043', 'CourseA', '3', '86', '2013-Summer'), ('10420844', 'CourseB', '4', '98', '2013-Autumn')]

由于我们需要为此库提供有效的xml,我们需要将您的内容包装在外部元素中,因此我们使用<table>%s</table>。这个元素的名字真的没关系;我使用 table ,因为你的数据看起来像来自一个html表。可以使用任何东西,因为我们选择了直接的子节点(不同的xpath表达式可能会限制我们可以用来避免冲突)。

一旦我们将数据读入ElementTree,我们就可以将findall与xpath表达式./tr一起使用,它可以找到内容中的所有 tr 元素。对于其中的每一项,我们使用./td来查找 td 元素。这些 text 属性将其内容作为文本获取。对元组的调用是匹配OP使用元组的所需输出。

存在更强大的xml库(例如lxml),并且ElementTree具有有限的xpath支持,但它足以解决此问题,并且它具有位于标准库中的优势。