python正则表达式没有捕到一些字段

时间:2014-07-13 04:44:14

标签: python html regex

大家好:我有一个字符串

s2 = '[u\'\\n\', <td><a href="/etf/UVXY/">UVXY</a></td>, u\'\\n\', <td><a href="/etf/
       UVXY/">Ultra VIX Short-Term Futures ETF</a></td>, u\'\\n\', <td class="rightnobr">+7'
pat = re.compile('<a href=.+>(.+)</a>')
re.findall(pat,s2) only returns ['Ultra VIX Short-Term Futures ETF']..

为什么它无法赶上['UVXY']字段?如果我做了

s22 ='[u\'\\n\', <td><a href="/etf/UVXY/">UVXY</a></td>, u\'\\n\', <td><'
re.findall(pat,s2) did return ['UVXY']

5 个答案:

答案 0 :(得分:3)

+是一个贪婪的运算符,因此<a href=.+>将捕获<a href="/etf/UVXY/">UVXY</a></td>, u\'\\n\', <td><a href="/etf/UVXY/">,其余的将由(.+)捕获。这就是为什么你只得到Ultra VIX Short-Term Futures ETF。你需要像这样非贪婪

pat = re.compile('<a href=.+?>(.+?)</a>')

<强>输出

['UVXY', 'Ultra VIX Short-Term Futures ETF']

如果您只将第一部分视为非贪婪,那么(.+)将匹配最后一部分</a>。所以,如果RegEx是

pat = re.compile('<a href=.+?>(.+)</a>')

然后输出

['UVXY</a></td>, u\'\\n\', <td><a href="/etf/UVXY/">Ultra VIX Short-Term Futures ETF']

这就是为什么你需要让贪婪的量词变得非贪婪,就像我的第一个例子一样。

答案 1 :(得分:1)

.+是贪婪的比赛。 (href=.+>匹配最后一个满足模式其余部分的>)使用非贪婪版本:.+?

>>> import re
>>> s2 = '[u\'\\n\', <td><a href="/etf/UVXY/">UVXY</a></td>, u\'\\n\', <td><a href="/etf/UVXY/">Ultra VIX Short-Term Futures ETF</a></td>, u\'\\n\', <td class="rightnobr">+7'
>>> pat = re.compile('<a href=.+?>(.+?)</a>')
>>> re.findall(pat,s2)
['UVXY', 'Ultra VIX Short-Term Futures ETF']

答案 2 :(得分:1)

问题是您的匹配是贪婪,其中模式消耗最多字符。从技术上讲,它实际上是贪婪的量词+。要获得non-greedy匹配,请使用+?

>>> pat = re.compile('<a href=.+?>(.+?)</a>')
>>> re.findall(pat, s2)
['UVXY', 'Ultra VIX Short-Term Futures ETF']

您也可以考虑使用tool作为工作。

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup(s2)
>>> links = [str(x.text) for x in soup.find_all('a')]
['UVXY', 'Ultra VIX Short-Term Futures ETF']

答案 3 :(得分:0)

Do not use regex for parsing HTML,使用名为HTML解析器的专用工具,如BeautifulSoup

import urllib2
from bs4 import BeautifulSoup

URL = 'http://etfdb.com/compare/volume/'

soup = BeautifulSoup(urllib2.urlopen(URL))
for row in soup.select('table.msdata tr')[1:]:
    print [td.text.strip() for td in row('td')]

打印:

[u'SPY', u'SPDR S&P 500', u'86,697,703', u'$172,868.1 M']
[u'EEM', u'iShares MSCI Emerging Markets ETF', u'46,298,734', u'$40,803.4 M']
[u'IWM', u'iShares Russell 2000 ETF', u'45,452,871', u'$25,882.6 M']
[u'QQQ', u'QQQ', u'35,422,355', u'$43,725.0 M']
...

答案 4 :(得分:0)

我没有足够的StackOverflow juice 发表评论,因此这显示为答案。我经常使用在线RE解析器来实验和测试我的RE。这是一个更好的,还包括一些好的文档:http://www.freeformatter.com/regex-tester.html