python中的正则表达式问题

时间:2020-03-06 14:19:59  来源:igfitidea点击:

好的,所以我正在使用正则表达式来搜索站点中的所有标头信息。

我已经编译了正则表达式:

regex = re.compile(r'''
    <h[0-9]>\s?
    (<a[ ]href="[A-Za-z0-9.]*">)?\s?
    [A-Za-z0-9.,:'"=/?;\s]*\s?
    [A-Za-z0-9.,:'"=/?;\s]?
''',  re.X)

当我在python reg ex中运行此命令时。测试仪,效果很好。

样本数据:

<body>
    <h1>Dog </h1>
    <h2>Cat </h2>
    <h3>Fancy </h3>
    <h1>Tall cup of lemons</h1>
    <h1><a href="dog.com">Dog thing</a></h1>
</body>

现在,在REDemo中,它的运行非常出色。

但是,当我将其放入python代码时,它仅显示&lt;a href="dog.com">

这是我的python代码,我不确定我是在做错什么,还是翻译中丢失了什么。我感谢帮助。

stories=[]
response = urllib2.urlopen('http://apricotclub.org/duh.html')
html = response.read().lower()
p = re.compile('<h[0-9]>\s?(<a href=\"[A-Za-z0-9.]*\">)?\s?[A-Za-z0-9.,:\'\"=/?;\s]*\s?[A-Za-z0-9.,:\'\"=/?;\s]?')
stories=re.findall(p, html)
for i in stories:
    if len(i) >= 5:
        print i

我还要注意,当我从正则表达式中取出((&lt;a href=\"[A-Za-z0-9.]*\">)?时,对非链接&lt;hN >行。

解决方案

请不要在python中手动解析html!有许多更好的选择。我会推荐美妙的BeautifulSoup

使用正则表达式解析事物适用于正则语言。 HTML不是一种常规语言,这些天我们在网页上找到的东西绝对是垃圾。 BeautifulSoup处理具有类似浏览器启发式功能的标记汤HTML,因此我们将获得类似于浏览器显示内容的已解析HTML。

缺点是它不是很快。有一个用于解析格式正确的html的lxml,但如果我们不确定100%确定输入将始终格式正确,则应该使用BeautifulSoup。

由于锚标签周围有花括号,因此该部分被解释为捕获组。这将导致仅返回捕获组,而不是整个正则表达式匹配项。

将整个正则表达式放在花括号中,我们将看到正确的匹配项显示为返回的元组中的第一个元素。

但是确实,我们应该使用一个真正的解析器。

在过去的几天中,已经以多种形式提出了这个问题,所以我要说得很清楚。

使用BeautifulSoup,html5lib或者lxml.html。请。

如前所述,我们应该使用解析器而不是正则表达式。

但是,这是使用正则表达式的方法:

import re

html = '''
<body>

<h1>Dog </h1>
<h2>Cat </h2>
<h3>Fancy </h3>
<h1>Tall cup of lemons</h1>
<h1><a href="dog.com">Dog thing</a></h1>
</body>
'''

p = re.compile(r'''
    <(?P<header>h[0-9])>             # store header tag for later use
    \s*                              # zero or more whitespace
    (<a\shref="(?P<href>.*?)">)?     # optional link tag. store href portion
    \s*
    (?P<title>.*?)                   # title
    \s*
    (</a>)?                          # optional closing link tag
    \s*
    </(?P=header)>                   # must match opening header tag
''', re.IGNORECASE + re.VERBOSE)

stories = p.finditer(html)

for match in stories:
    print '%(title)s [%(href)s]' % match.groupdict()

这里有一些很好的正则表达式资源:

  • Python正则表达式HOWTO
  • Regular-Expressions.info

到目前为止的答案:

最好使用解析引擎。它可以以优雅的方式涵盖很多情况。我尝试过BeautifulSoup,我非常喜欢。也很容易使用,提供了出色的教程。

如果有时感觉像用大炮射击苍蝇,则可以使用正则表达式进行快速解析。如果我们需要的是经过修改的代码,它将捕获所有标头(即使是多行标头):

p = re.compile(r'<(h[0-9])>(.+?)</>', re.IGNORECASE | re.DOTALL)
stories = re.findall(p, html)
for i in stories:
    print i

我已经使用beautifulsoup来解析我们所需的HTML。我在上面的HTML代码中
名为foo.html的文件,以后又作为文件对象读取。

from BeautifulSoup import BeautifulSoup

H_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']

def extract_data():
   """Extract the data from all headers
   in a HTML page."""
   f = open('foo.html', 'r+')
   html = f.read()
   soup = BeautifulSoup(html)
   headers = [soup.findAll(h) for h in H_TAGS if soup.findAll(h)]
   lst = []
   for x in headers:
      for y in x:
         if y.string:
            lst.append(y.string)
         else:
            lst.append(y.contents[0].string)
   return lst

上面的函数返回:

>>> [u'Dog ', u'Tall cup of lemons', u'Dog thing', u'Cat ', u'Fancy ']

我们可以在h_tags列表中添加任意数量的标题标签。我已经假设了所有标题。
如果我们可以使用BeautifulSoup轻松解决问题,那么最好使用它。 :)