今天在看大神的博客正则基础之——反向引用的时候突然看到一个链接一条正则能不能同时取出一个img标记的src和name?
就点进去 看了下 ,想了想这个问题,
/<input\b[^<>]*(?:(?:name=)(?:"|')(\w+)|(?:id=)(?:"|')(\w+))[^<>]*(?:(?:id=)(?:"|')(\w+)|(?:name=)(?:"|')(\w+))[^<>]*>$/i;(我的初学水平。。。)
匹配是能匹配上了,关键的问题是,目标字符串中name和id的位置一变,匹配出来的结果的位置也变了,不是很好。。
然后我就看了大神写的正则
/<img\b(?=(?:(?!name=).)*name=(['"]?)([^'"\s>]+)\1)
(?:(?!src=).)*src=(['"]?)([^'"\s>]+)\3[^>]*>/i
而这句正则居然是在字符串中name和src的位置变了的时候,匹配结果的位置并未改变!!!
看了好半天,终于发现了玄机,?=预匹配,预查不消耗字符。也就是说,在?=后的部分匹配完成之后,又会回到开始的地方进行匹配。
这样就可以无论name和src的顺序都能匹配成功。
同时,注意这个部分,(['"]?)([^'"\s>]+)\1),这里用到了反向引用,刚开始我还在想,['"]?这么简单的模式,再写一个不就好了,为什么要用反向引用?
后来仔细一想,这里需要配对,一定得用反向引用,要不"test'也会匹配成功。
我不禁感叹在编程学习的过程中,多看大神的代码是多么重要的一件事!