Python -- 正则表达式 -- 如何在两个字符串之间查找一个字符串

6

请考虑以下内容:

<div id=hotlinklist>
  <a href="foo1.com">Foo1</a>
  <div id=hotlink>
    <a href="/">Home</a>
  </div>
  <div id=hotlink>
    <a href="/extract">Extract</a>
  </div>
  <div id=hotlink>
    <a href="/sitemap">Sitemap</a>
  </div>
</div>

你如何使用正则表达式在 Python 中删除 sitemap 行?
<a href="/sitemap">Sitemap</a>

以下代码可用于提取锚点标签。
'/<a(.*?)a>/i'

然而,有多个锚点标签。此外,还有多个热链接,所以我们也无法使用它们吗?


你可能听说过正则表达式不适合解析类似HTML这样的上下文无关语言。 - Gumbo
2
如果您是生成HTML的人,值得注意的是,多个相同的id =属性是无效的。class =更合适。 - Ben Blank
4个回答

13

不要使用正则表达式,而应该使用BeautifulSoup,一个HTML解析器。

from BeautifulSoup import BeautifulSoup

html = \
"""
<div id=hotlinklist>
  <a href="foo1.com">Foo1</a>
  <div id=hotlink>
    <a href="/">Home</a>
  </div>
  <div id=hotlink>
    <a href="/extract">Extract</a>
  </div>
  <div id=hotlink>
    <a href="/sitemap">Sitemap</a>
  </div>
</div>"""

soup = BeautifulSoup(html)
soup.findAll("div",id="hotlink")[2].a

# <a href="/sitemap">Sitemap</a>

6

使用正则表达式解析HTML是一个坏主意!

思考下面的一段HTML代码:

<a></a > <!-- legal html, but won't pass your regex -->

<a href="/sitemap">Sitemap<!-- proof that a>b iff ab>1 --></a>

还有许多类似的例子。正则表达式很适合做很多事情,但不适合解析HTML。

你应该考虑使用Beautiful Soup Python HTML解析器。

无论如何,使用正则表达式的临时解决方案是

import re

data = """
<div id=hotlinklist>
  <a href="foo1.com">Foo1</a>
  <div id=hotlink>
    <a href="/">Home</a>
  </div>
  <div id=hotlink>
    <a href="/extract">Extract</a>
  </div>
  <div id=hotlink>
    <a href="/sitemap">Sitemap</a>
  </div>
</div>
"""

e = re.compile('<a *[^>]*>.*</a *>')

print e.findall(data)

输出:

>>> e.findall(data)
['<a href="foo1.com">Foo1</a>', '<a href="/">Home</a>', '<a href="/extract">Extract</a>', '<a href="/sitemap">Sitemap</a>']

如果你用 (?:[^<]+|<(!/a\b))* 替换掉 .*,你将会得到更少的假阳性结果,而且不会因为回溯而使正则表达式引擎崩溃。 - Ben Blank

5
为了提取标语的内容:
    <a href="/sitemap">Sitemap</a>

如果我要使用,我会选择:

    >>> import re
    >>> s = '''
    <div id=hotlinklist>
    <a href="foo1.com">Foo1</a>
      <div id=hotlink>
        <a href="/">Home</a>
      </div>
      <div id=hotlink>
        <a href="/extract">Extract</a>
      </div>
      <div id=hotlink>
        <a href="/sitemap">Sitemap</a>
      </div>
    </div>'''
    >>> m = re.compile(r'<a href="/sitemap">(.*?)</a>').search(s)
    >>> m.group(1)
    'Sitemap'

实际上,将站点地图替换为XYZ,因为它确实可以是任何内容。我只知道它是hotlinlist div中的第3个div。使用的HTML模式可以重复多次。假设我想在ebay上列出所有智能手机清单。我会知道上述模式对于找到的每个智能手机都会重复,但是<a herf="XYZ">XYZ</a>可以是iPhone、黑莓、诺基亚或任何其他智能手机。可能没有物品或100个以上。因此,我正在寻找一些东西,可以查找重复的模式,然后取出智能手机行,并列出智能手机清单。 - Avid Coder
我喜欢这个答案,因为它回答了问题。而且不管你信不信,它还帮助我更好地理解了正则表达式。 - Max

1

如果您需要解析HTML,请使用BeautifulSouplxml

另外,您真正需要做什么?找到最后一个链接?找到第三个链接?找到指向/sitemap的链接?从您的问题中无法确定。您需要对数据进行什么操作?

如果您确实必须使用正则表达式,请查看findall


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接