工作需要,用到在java中提取微信公众号文章内的背景图地址,深入了解了一下正则表达式的反向引用、环视的概念,发现非常好用,节省了很多代码,以下是最终提取CSS中背景图地址的正则表达式:1
(background|background\-image)\s*:\s*url\s*\(\s*(('|"|")?)\s*([^\s]+)\2\s*\)
简单解释一下:
(background|background\-image):首先匹配background或background-image属性\s*:第1步之后可以跟任意数量的空白字符:第2步之后必须跟一个英文冒号\s*:第3步之后可以跟任意数量的空白字符url:第4步之后必须跟一个字符串,内容为url\s*:第5步之后可以跟任意数量的空白字符\(:第6步之后必须跟小括号的左半部分,\是对(进行转义\s*:第7步之后可以跟任意数量的空白字符(('|"|")?):第8步之后可以有或者没有'、"或"\s*:第9步之后可以跟任意数量的空白字符([^\s]+):第10步之后需要跟至少一个非空白字符,这里匹配的即为背景图的完整地址,综合考虑到背景图地址可以是绝对地址和相对地址,以及实际场景(即背景图地址可以被单引号、双引号或"引起来,如"http://domain.com/a.jpg",但不会出现一端是单引号或双引号,另一端不是单引号或双引号的情况,如'http://domain.com/a.jpg"或"http://domain.com/a.jpg"),因此这里认为可以包含任意非空白字符\2:第11步之后跟一个字符,内容与第9步匹配的内容相同\s*:第12步之后可以跟任意数量的空白字符\):最后跟上小括号的的右半部分,和第7步匹配的对应
考虑到微信公众号文章内的背景图地址不可能是相对地址,这里可以对第11步进行优化,由([^\s]+) 改造为 (\/\/|http\:\/\/|https\:\/\/)([^\s]+) ,即匹配地址必须以 // 、http:// 或 https:// 开头,因此,针对提取微信公众号内文章的背景图地址,优化后的正则表达式如下:1
(background|background\-image)\s*\:\s*url\s*\(\s*(('|"|")?)\s*(\/\/|http\:\/\/|https\:\/\/)([^\s]+)\2\s*\)
参考资料:深入理解正则表达式环视的概念与用法