2016-02-06 73 views
-2
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 

输出是:蟒蛇re.findall没有找到所有

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

但该预期的结果:

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

其实这个代码只返回了最后一场比赛,如果有超过2场比赛。谁能告诉我为什么会发生这种情况?对不起长码,并提前致谢!

+4

不,不要使用RegEx解析HTML。 –

+1

随着凯文说 - [读这篇着名的文章](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) –

+0

谢谢。那么我应该怎么做才能找到所有的比赛?其实我可以将HTML转换为str,所以我仍然想知道这里有什么问题。 – Simon

回答

2

你可以像下面BeautifulSoup做到这一点:

>>> from bs4 import BeautifulSoup 
>>> 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> 
... """ 
>>> 
>>> soup = BeautifulSoup(content, "html.parser") 
>>> [i.get_text(' ').split() for i in soup.find_all('tr')] 
[['12090043', 'CourseA', '3', '86', '2013-Summer'], ['10420844', 'CourseB', '4', '98', '2013-Autumn']] 

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

+0

非常感谢。但为什么每个元素之前都有一个字母“u”?像[u'12090043',u'CourseA',u'3']。感谢您的时间!! – Simon

+0

@Simon:我想你使用的是Python 2,这意味着输出是unicode字符串。请参阅:[字符串值前面的'u'符号是什么意思?](http:// stackoverflow。COM /问题/ 11279331 /什么,做最U型符号均在-前的字符串值)。噢,如果有帮助的话,请记住请回答这个问题。另请参阅:[如何接受答案的工作?](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) –

+0

接受。谢谢你的帮助。 – Simon

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>。这个元素的名字真的没关系;我使用,因为您的数据看起来像来自html表格。任何事情都可以使用,因为我们选择直接的子节点(不同的xpath表达式可能会限制我们可以用来避免冲突)。

一旦我们已经将数据读入ElementTree,我们可以使用findall与xpath表达式./tr,它会在内容中找到所有元素。对于这些中的每一个,我们使用./td来找到td元素。这些文件的文本属性获取它们的内容作为文本。对元组的调用是匹配使用元组的OP的期望输出。

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

+0

只是好奇。你说你使用'table'来生成有效的XML。使用不是HTML标签的标签名称不会与任何内容发生冲突是否合理?例如,'%s'有效吗? –

+0

正如我所说,我只是因为输入看起来像一个HTML表,但如上所述,任何东西都可以使用。在这种情况下,因为我们要选择直接的子节点,所以我可以在没有冲突威胁的情况下使用任何东西(甚至是_tr_)。 – Matthew

+0

Gotcha。我很少使用Xpath或ElementTree库,这就是为什么我问 –