【问题标题】:python regular expression find and replace html tag with specific attribute valuepython正则表达式查找并替换具有特定属性值的html标签
【发布时间】:2013-12-17 16:57:56
【问题描述】:

我正在尝试在 python 中编写一个正则表达式,它将找到所有 src 属性等于特定值的 img 标签。我尝试编写以下内容

   # where thm equal /public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82
   p = re.compile(r'<img.*?%s.*?>' % thm)
   print p.pattern
   print p.sub(linked_image, c)

低于我得到的输出

<img.*?/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82.*?>

<p><img src="/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82" alt=""></p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 
</p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf 

【问题讨论】:

  • 在这项工作中使用 BeautifulSoup 怎么样? crummy.com/software/BeautifulSoup
  • 我可以使用 beautifulSoup,但正在更改非结构化内容,它应该保持其结构不变。 BeautifulSoup 的问题,我将无法将处理后的汤输出到以前的结构作为输出...这就是为什么我需要更改替换字符串方法
  • 请看一下新版本——我在原始的thm变量中发现了错误,并在下面提出了两个解决方案。

标签: python regex


【解决方案1】:

使用 LXML 的解决方案

为了将解决方案与正则表达式和 LXML 进行比较,我创建了另一个帖子:

更简单、更稳定的解决方案是将lxmletree 结合使用。在那个解决方案中,你 访问某些 DOM 元素并编辑它们。

转换 HTML 字符串并通过正确的xpath 获取它,例如.//imgxpath 返回所有找到的元素列表,您可以在其中找到 getset src 属性。 函数etree.tostring(tree) 返回一个编辑后的字符串:

from lxml import etree
tree = etree.HTML('''<html>
                     <body>
                        <h1>Title</h1>
                        <img src="/media/old/another_logo.png" alt="" />
                        <p>Lorem Ipsum</p>
                        <p><img src="/media/old/logo.png" alt=""/></p>
                     </body>
                  </html>''')

imgs = tree.xpath('.//img')

for img in imgs:
    print 'OLD_SOURCE', img.get('src')
    img.set('src', '/media/new/python.jpg')

print etree.tostring(tree)

输出

OLD_SOURCE /media/old/another_logo.png
OLD_SOURCE /media/old/logo.png

<html>
    <body>
        <h1>Title</h1>
            <img src="/media/new/python.jpg" alt=""/>
            <p>Lorem Ipsum</p>
            <p><img src="/media/new/python.jpg" alt=""/></p>
    </body>
</html>

【讨论】:

    【解决方案2】:

    正则表达式解决方案

    我意识到插入thm 的字符串没有被转义。 因此,在将其添加到正则表达式之前,您需要使用转义所有符号 正则表达式语言中的附加含义 - 这里是?.

    我将? 替换为[?]{1},将. 替换为\.。生成的正则表达式现在匹配测试字符串。

    import re
    thm = '/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82'
    
    all_html_code = '''<img.*?/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82.*?>
    
    <p><img src="/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82" alt=""></p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf
    </p><p>lksj lksdfj lsdkfj sldkfj sldkfj lskdfj lsjf lksjf lksj flksdjf klsj flk dkj sdlkfj sdlkfj sldkjf sldkfj lsdkjf lskjflsjfsl lksdjf '''
    
    escaped_thm = thm.replace('.', '\.').replace('?','[?]{1}')
    p = re.compile(r'<img.*?src="(%s)".*?>' % escaped_thm)
    
    test_img = '''<img src="/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82" alt="">'''
    print p.match(test_img)
    
    new_img_tag = '<img src="/python/logo.jpg" alt=""/>'
    print p.sub(new_img_tag, all_html_code)
    

    对了,你为什么要找&lt;img src=""...&gt;?您可以直接替换 src 属性:

    escaped_thm = thm.replace('.', '\.').replace('?','[?]{1}')
    p = re.compile(r'src="(%s)"' % escaped_thm)
    
    replacement = '''src="/python/logo.jpg"'''
    print p.sub(replacement, all_html_code)
    

    输出 1

    <_sre.SRE_Match object at 0x... >
    <img.*?/public_media/cache/84/b5/84b59e293cbdb7041b68a84977d62cf3.jpg?image_pk=82.*?>
    
    <p><img src="/python/logo.jpg" alt=""/></p><p>lksj lksdfj ... lksdjf 
    

    输出 2

    <p><img src="/python/logo.jpg" alt=""></p><p>lksj lksdfj ... lksdjf 
    

    在询问了转义正则表达式符号的正确方法 (Regular expression to escape regular expressions) 之后 - 我可以推荐一个 re.escape 而不是两个 replace 方法。

    使用 LXML

    你需要使用正则表达式吗? HTML 的正则表达式可能存在很大问题。在此处查看更多信息和精彩帖子(RegEx match open tags except XHTML self-contained tags)。

    我宁愿像这里那样使用 XPath。

    【讨论】:

    • 我可以使用 beautifulSoup,但正在更改非结构化内容,它应该保持其结构不变。 BeautifulSoup 的问题,我将无法将处理后的汤输出到以前的结构作为输出...这就是为什么我需要更改替换字符串方法
    • 我用正则表达式添加了一个解决方案。请查看上面的示例。
    猜你喜欢
    • 1970-01-01
    • 2012-02-18
    • 2017-07-15
    • 2019-04-12
    • 2022-12-11
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多