在我写上一个试题管理项目时,有一个需求是需要匹配HTML文档节点的,因为有些试题是有图片的,所以需要把图片给匹配出来,他储存在数据库的形式如下:
“<img src=”../xxx/xx/x/x.png”>xxxxxxxxxxxxxxxxxxxxxxxxxxxxx ~~A.xxx ~~B.xxx ~~C.xxx ~~D.xxx”。我需要把其中的img给匹配出来。
我的第一版答案:/<.+>/结果如下:
确实这样可以把里面的图片匹配出来,但是这个有缺陷。我解释下里面用到的知识点: “.”是匹配任意字符,“+”是匹配多次,所以/<.+>/就是说匹配以”<”开头,中间多个任意字符,以“>”结尾。那么很明显他的缺陷就是当试题中不只有一张图片时他的匹配规则无法满足。图示:
当有两个图片夹着试题内容时,他会把试题给匹配出来,这不符合我们的需求。所以,改
分析为什么会出先这种情况。
注:/<.+>/的匹配规则:匹配以”<”开头,中间多个任意字符,以“>”结尾。
根据上述匹配规则得出结论。
在“<img src=”../xxx/xx/x/x.png”>xxxxxxxxxxxxxxxxxxxxxxxxxxxxx<img src=”../xxx/xx/x/x.png”> ~~A.xxx ~~B.xxx ~~C.xxx ~~D.xxx”中符合匹配的有多种。
而正则默认也许是匹配最大范围的:这里用集合的包含关系很好理解。
符合1:<img src=”../xxx/xx/x/x.png”>
符合2:<img src=”../xxx/xx/x/x.png”>xxxxxxxxxx<img src=”../xxx/xx/x/x.png”>
2包含了1,所以他直接跳过了第一个“>”匹配最后一个“>”。
所以这里要用到另一个正则小知识:?
“?”是懒惰匹配,如字面意思,当有符合的匹配项时停止匹配,返回结果。
那么该把“?”放在哪呢。嘿嘿,我想应该有人会想到这个结果:/?<.+>/g。(手动滑稽)
这个是错的。
最终结果:/<.+?>/g,匹配结果如下:
但!这就完美了吗?实则不然,回想下标题:匹配标签。
如果其中不单单有图片标签,试题用了p标签呢?
<img src=”../xx/xx/xxx/x.png”><p>xxxxxxxxxxxxxxxxxxxxxxxx</p>,那么它又炸了。结果:
其实这个想要解决也简单:只需要给他指定匹配哪个标签就行,众所周知:HTML文档的标签都有自己的节点名那么我们只需要基于上面的基础,给他指定匹配img就能解决
那么最最终版答案:/<img.+>/g,下图结果: