正则表达式,如何匹配html里面<img[^>]*>以外的内容?

比如这段html,最终结果只需要两个图片:

老...<p class="reslinkinfo">新浪文娱</p>李冰冰承认李雪是mm 李冰冰真实年龄42?(图)_文娱_腾讯网<img src="https://p.ssl.qhimg.com/dmsmfl/120_75_/t013e8ac02be9c39957.jpg?size=246x379&phash=3264502081370932440" ><br><br>毕竟,当对李雪满怀感激打动之心的李冰冰看到她穿上婚纱,一步步走向幸福那刻,情难自禁,兴奋暗示:“作为姐姐,我毕竟可以欣慰啦。”而后,她更略有歉...<p class="reslinkinfo">腾讯文娱</p>李冰冰mm李雪照片曝光 两人像极双胞胎(组图)搜狐青岛<img src="https://p.ssl.qhimg.com/dmsmfl/120_75_/t01641ca782482f584f.jpg?size=500x333&phash=6529213026346063041" ><br><br>恰逢父亲节

试过.*?(?=<img[^>]*>)
会把前面的一个img里的内容也取到.

阅读 7.3k
4 个回答

因为你没有指定语言, 我就用最擅长的Ruby吧. 通常, 遵循Perl风格的正则都应该可以执行.

方案一

pat = /<img\s+src="(.*?)".*?>/

说明:

  • \s+表示匹配一个或多个空格, 因为imgsrc之间至少一个空格

  • ()表示组, 可以反向引用, 参见我的另一个回答

  • .*?表示懒惰匹配, 找最近的以下一个字符结尾的, 相当于[^"]*[^>]*

方案二

pat = /(?<=<img src=").*?(?=".*?>)/

说明:

  • (?<=)表示前导串匹配, 即作为匹配串的前导字串, 但并不包含在匹配中

  • (?=)表示位置串匹配, 即此处应该匹配此字串, 但并不包含在匹配中

  • 常用上面两个来定位想要字串的前后字串, 但又不想包括前后字串

运行

str.scan(pat) {|item| puts item}  # 输出匹配的内容

两个方案有些许区别, 方案一, 实际上整个<img ...>标签都会被匹配, 但是可以反向引用匹配组(). 在Ruby中, 传递给块参数的是匹配组, 因此可以使用, 别的语言应该有相似的机制. 方案二, 实际上只匹配标签的src属性的值, 即你想要的图片.

但方案二有个问题, 前导串匹配要求长度固定. 也就是说, 当imgsrc有不确定长度的空白时, 并不能写作(?<=<img\s+src="). 前导串匹配的匹配是<img\s+src=", 其长度不固定, 所以不能写成这样.

因为推荐方案一, 且大部分语言的正则都支持反向引用, 而前导串和位置串匹配并不一定支持, 这算非常高级的内容.

注解

?<=术语zero-width positive lookbehind, 前导串匹配是我自己生造的, 虽然我觉得更贴切

?=术语zero-width positive lookhead, 同上.

也有翻译为零宽度位置匹配.

你可以搜索一下正则的捕获组

<(img|IMG)[^\<\>]*>
/<img[^>]+>/ig
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进