阅读:65391回复:51
AdBlock正则表达式实践心得[by kmc](2005/12/16附件更新)
首先,我尚且不懂javascript,以下心得,完全是通过学习正则表达式的文档和实践得出,
写该文的目的之一也是试图消除大家对正则表达式的畏惧心理,从简单之处先入门。 而这其中必定有贻笑大方之处,恳请高手们斧正! 在看本文之前,我在附件中附上了带我进入正则表达式之门的一个基础教程, 和一个“正则表达式的练习器”,建议大家先读此文并粗略的实践一下,因为 下面的文字都站在这篇文章的基础上。 --------------------------------------------------------------------------------------------- 通过对正则表达式的文档的研究,以及对本人Maxthon积累下来的广告过滤条目对应的url的分析, 我有以下几点心得: 1.正则表达式的优势,在于高整合度和高精确度,记做到了代码的简洁,又疏而不漏,唯一的缺点,不过是 可读性略差了一点。 2.理论上说,所有的过滤条目都可以用|符号整合到一条正则表达式过滤器里面去,可是这样既雪上加霜地降低了 可读性,还不可避免地失去了正则表达式高整合度的优势。所以,为了能写出好的正则表达式,分析需要匹配的 文本(在这里就是url了)是必不可少的。 ************************************************************************************* 我们常见的url无非是:aaa.bbb.ccc/123456789/........htm,gif等等 需要过滤的地址,由抽象到具体来说,往往有以下特点: I.全部过滤一个不漏,只要出现就喀嚓,往往是令人深恶痛绝的url。 例(例子中都是用原始的带通配符的表达式):*.ad.*; */ad/*; *.3721.*/*或者*3721* II.过滤网址主体,也就是第一个/号之前的所有。 例:www.1000downloads.com/*; <!-- w --><a class="postlink" href="http://www.w163.com/*">www.w163.com/*</a><!-- w --> III.过滤具体到网页子目录,进入若干个/号内 例:http://imguv.21cn.com/images/*; http://union.homeway.com.cn/images/* 之所以能这样,一般是因为一眼看过去就知道这样的目录下没有好东西,或者看到很多条过滤器中 都出现如下的结构(也表明了网页作者的风格类似),如这里的images IV.过滤具体到文件,一般就是*.gif,*.swf,*.js类的文件了 例:http://images.chinabyte.com/*.swf; http://www.5ud.com/images/*.gif 综上,只要把问题分开考虑即可: ************************************************************************************** 1.一段体 创建一个如下的表达式(注:本文的正则表达式如果不带前后的两个/号,加入adblock时需加上) (\.|\/)(您的输入)(\.|\/|_) (感谢zlowly给出这个filter模型) 前后两个括号中表示的是在你的字段前出现"."或"/",字段后出现".","/"或"_"时候考虑你的字段, 没有这两个限制的话过滤范围就过宽了,例:只写(ad)的话,任何带有ad二字的url均会被过滤。 例: /(\.|\/)(tomnews|dns99|ad|banner|3721|taobao|unionsky)(s)?(\d)*(\.|\/|_)/ --其中的(s)?是表示s出现0次或1次,则该filter通配ad或者ads,banner或banners,但由于 可以出现0次,所以其他成分仍然可以往中间的括号里加入,即便没有unionskys,taobaos。 --后面的(\d)*表示0-9之间的数字,*号表示0次或多次。 正如zlowly所说,为的是对抗网站根据日期显示不同广告,例如 .../ad20041020/... 然后无非是在中间那个括号中,用|号分开你所有想要匹配的字段了。 知道了这一点,后面的情况就势如破竹了。 2.二段体 创建一个这样的表达式雏形: \.()\.() 由于已经具体到网址的主体部分,所以前后的/或者.也就不需再出现了 例: \.(boyis|allyes|cjt1|w163|ppzxw|1000downloads)\.(net|com) 它等价于 http://*.allyes.com/* *.boyis.com* *.cjt1.net* *.w163.com* *.ppzxw.com* *.1000downloads.com* 这样看来,应该比较清晰了吧? 3.三段体 例: (union|adimg|unstat|ulinkjs)\.(baidu|tom|163|sogou)\.(com) 等价于 *adimg.163.com* *unstat.baidu.com* *ulinkjs.tom.com* *union.sogou.com* 或许有朋友问,为什么分开三种情况呢?整合到一起去有没有可能? 一个很自然的想法是用一个"?"号来表示三段体中的第一段或者出现,或者不出现, 例如想要整合admig.163.com和*.boyis.com,这样写的话: (adimg)?\.(163|boyis)\.(com) 因为adimg这个字段可出现也可不出现,所以实际上www.163.com这样的地址自然也会被匹配上了,这可不是我们的初衷, 这也就是为什么我觉得应该把各种情况分开考虑,当然更期待高手能解决这个 问题。 其次,鉴于"|"符号会导致自由组合,整合度不应太高。三段体例子中,第一个括号中最好不要放进通用性太强的字段, 如www,否则"|"符号产生自由组合,若要过滤www.ads8.com和adimage.163.com,自由组合的结果当然www.163.com也被过滤了…… 有鉴于此,锁定某一段应该是一个不错的选择,我看第三段应该锁定,也就是说里面没有“或”符号 例如:结尾为com的全部单独写一条,而不要结尾(com|net|org|biz|gov)全加上, 或许会有意想不到的组合的(大家看看whitehouse.com/net/gov就知道了:)) 4.具体到文件的,swf/gif类(如有FlashBlock这个扩展的,可以不需要重复过滤swf) 下面是一条很个人的filter,原则也就是在()\.()\.()\/的基本型后面加上了一个.*\.(gif|swf)的文件类型判断, 鉴于这个时候网站网址变化很大,这个filter的整合度就不高了,很多都是直接贴进去然后用"|"符号分开而已。 (www\.(mydrivers|btbbt|shd|5ud)\.com(\.cn)?|search(\d)?\.btchina\.net|image\.cgame\.cn| onlinedown\.net|218\.106\.83\.10|down\.20cl\.com)\/(image(s)?|photo)?\/.*\.(gif|swf) 等价于: http://*.onlinedown.net/*.swf http://*.onlinedown.net/images/*.gif http://down.20cl.com/*.gif http://image.cgame.cn/photo/*.gif http://search3.btchina.net/images/*.gif http://www.btbbt.com/*.gif http://www.shd.com.cn/*.gif http://www.mydrivers.com/images/*.gif http://www.mydrivers.com/images/*.swf http://218.106.83.10/images/*.gif ***************************************************************************************************************** 希望拙作能给大家体会正则表达式的强大、学习使用正则表达式带来帮助。 在此最有必要感谢的是AdBlock的(作者(们)?)(0次或1次……呵呵),我在AdBlock的设置中也没找到他(们)?的名字, 网站上也没找到,对这样默默无闻的人表示敬佩。 顺带谢谢提供广告帮助测试AdBlock的所有广告提供商…… |
|
|
1楼#
发布于:2004-11-30 00:19
我也来学习了!!
|
|
2楼#
发布于:2004-11-30 00:19
|
|
|
3楼#
发布于:2004-11-30 00:19
貌似很正确的 ad\d+\.(gif|jpg) 岂不是产生无数个匹配条件,永远算不完 |
|
4楼#
发布于:2004-11-30 00:19
应该是 vb 和 dephi,打错字。 -__-!!
|
|
|
5楼#
发布于:2004-11-30 00:19
|
|
6楼#
发布于:2004-11-30 00:19
最近正则在 maxthon 论坛很火,有人转了这个帖子。看了看,感觉大家对正则或过滤似乎还是不太掌握,在 maxthon 论坛提了些意见,顺便在这里分享一下。
首先过滤速度主要视乎过滤规则的复杂性,或匹配条件的多少,而非过滤规则多少。所以不要把匹配条件都免勉强跻进同一规则。一条效率低的规则可以比十条规则慢。 像顶楼例子: 3.三段体 这里本来只有 4 个匹配条件: adimg.163.com unstat.baidu.com ulinkjs.tom.com union.sogou.com 有效的写法为 (adimg.163|unstat.baidu|ulinkjs.tom|union.sogou)\.com 红色部份更加可省略,减低处理量。 但用上面写法 (union|adimg|unstat|ulinkjs)\.(baidu|tom|163|sogou)\.(com) 便产生 16 个匹配条件: union.baidu.com adimg.baidu.com unstat.baidu.com ulinkjs.baidu.com union.tom.com adimg.tom.com unstat.tom.com ulinkjs.tom.com union.163.com adimg.163.com unstat.163.com ulinkjs.163.com union.sogou.com adimg.sogou.com unstat.sogou.com ulinkjs.sogou.com 不用说效率及准确度都差得多了。 另外大家都知道 adblock 是用 javascript 编写的,而 javascript 是 interpret 语言,速度一般只有 c++,vs,dephani 等 compiled language/machine code 的 10 到 20 分之一,不适宜作大量运算,否则会做成像某版主说的用 css 下载隐藏感觉上比用 adblock 直接过滤还更快。 |
|
|
7楼#
发布于:2004-11-30 00:19
问一下.正则表达式里通配符是什么?好象不是*吧.还有[]括号是什么含义?
|
|
|
8楼#
发布于:2004-11-30 00:19
Freewebs Page Not Found ....... |
|
9楼#
发布于:2004-11-30 00:19
谢谢楼主 才发现原来ADblock功能这么强大 试了一下 很爽 看到不爽的就可以cancel掉
|
|
10楼#
发布于:2004-11-30 00:19
很多的链接无效了。
|
|
11楼#
发布于:2004-11-30 00:19
汗,附件裏怎么是亂碼啊!!!!!!!!!!
|
|
12楼#
发布于:2004-11-30 00:19
.crsky.com/Ggao/*.gif
.crsky.com/Ggao/*.jpg .crsky.com/Ggao/*.swf 这三个合在一起用正则表达式如何写? 自己瞎写的/Ggao\.(swf|gif|jpg)/*不行~~ |
|
13楼#
发布于:2004-11-30 00:19
虽然不是很懂,但总算学了点,相当不错,
经常浏览的网站的SWF和GIF都统统消失啦! 正则万岁! ADBLOCK万岁! FF万岁! 自由万岁! IE跟毛毛虫睡! |
|
|
14楼#
发布于:2004-11-30 00:19
我如何写这样的表达式来提取数据?
<META name="description" content="浙江省最大的综合性网站,宁波的门户站点。内容涵盖游戏、证券、电脑、旅游、企业、书楼、贺卡、人才、娱乐、时尚、汽车、直播、导航、论坛、聊天、美术、手机、体育、数码、音乐、生活、硬件、软件、网吧、影库、房产、影院等等。">
<meta name="keywords" content="游戏;证券;电脑;旅游;企业;书楼;贺卡;人才;娱乐;时尚;汽车;直播;导航;论坛;聊天;美术;手机;体育;数码;音乐;生活;硬件;软件;网吧;影库;房产;影院"> 我想提取上面部分的Content的值 同时我想提取下面部分的charset的值,如何用正则表达式表述? <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> |
|
上一页
下一页