工作需要,用到在java中提取微信公众号文章内的背景图地址,深入了解了一下正则表达式的反向引用、环视的概念,发现非常好用,节省了很多代码,以下是最终提取CSS中背景图地址的正则表达式:
(background|background\-image)\s*:\s*url\s*\(\s*(('|"|")?)\s*([^\s]+)\2\s*\)
简单解释一下:
1. (background|background\-image)
:首先匹配background
或background-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*\)
参考资料:深入理解正则表达式环视的概念与用法