工作需要,用到在java中提取微信公众号文章内的背景图地址,深入了解了一下正则表达式的反向引用、环视的概念,发现非常好用,节省了很多代码,以下是最终提取CSS中背景图地址的正则表达式:

(background|background\-image)\s*:\s*url\s*\(\s*(('|"|")?)\s*([^\s]+)\2\s*\)

简单解释一下:
1. (background|background\-image):首先匹配backgroundbackground-image属性
2. \s*:第1步之后可以跟任意数量的空白字符
3. :第2步之后必须跟一个英文冒号
4. \s*:第3步之后可以跟任意数量的空白字符
5. url:第4步之后必须跟一个字符串,内容为url
6. \s*:第5步之后可以跟任意数量的空白字符
7. \(:第6步之后必须跟小括号的左半部分,\ 是对 ( 进行转义
8. \s*:第7步之后可以跟任意数量的空白字符
9. (('|"|")?):第8步之后可以有或者没有'""
10. \s*:第9步之后可以跟任意数量的空白字符
11. ([^\s]+):第10步之后需要跟至少一个非空白字符,这里匹配的即为背景图的完整地址,综合考虑到背景图地址可以是绝对地址和相对地址,以及实际场景(即背景图地址可以被单引号、双引号或 " 引起来,如"http://domain.com/a.jpg",但不会出现一端是单引号或双引号,另一端不是单引号或双引号的情况,如 'http://domain.com/a.jpg""http://domain.com/a.jpg"),因此这里认为可以包含任意非空白字符
12. \2:第11步之后跟一个字符,内容与第9步匹配的内容相同
13. \s*:第12步之后可以跟任意数量的空白字符
14. \):最后跟上小括号的的右半部分,和第7步匹配的对应

考虑到微信公众号文章内的背景图地址不可能是相对地址,这里可以对第11步进行优化,由([^\s]+) 改造为 (\/\/|http:\/\/|https:\/\/)([^\s]+) ,即匹配地址必须以 //http://https:// 开头,因此,针对提取微信公众号内文章的背景图地址,优化后的正则表达式如下:

(background|background\-image)\s*\:\s*url\s*\(\s*(('|"|")?)\s*(\/\/|http\:\/\/|https\:\/\/)([^\s]+)\2\s*\)

参考资料:深入理解正则表达式环视的概念与用法

About Me
WEB开发工程师
GitHub Repos