首先,我尚且不懂javascript,以下心得,完全是通过学习正则表达式的文档和实践得出,
写该文的目的之一也是试图消除大家对正则表达式的畏惧心理,从简单之处先入门。
而这其中必定有贻笑大方之处,恳请高手们斧正!


在看本文之前,我在附件中附上了带我进入正则表达式之门的一个基础教程,
和一个“正则表达式的练习器”,建议大家先读此文并粗略的实践一下,因为
下面的文字都站在这篇文章的基础上。

---------------------------------------------------------------------------------------------



通过对正则表达式的文档的研究,以及对本人Maxthon积累下来的广告过滤条目对应的url的分析,
我有以下几点心得:
1.正则表达式的优势,在于高整合度和高精确度,记做到了代码的简洁,又疏而不漏,唯一的缺点,不过是
可读性略差了一点。
2.理论上说,所有的过滤条目都可以用|符号整合到一条正则表达式过滤器里面去,可是这样既雪上加霜地降低了
可读性,还不可避免地失去了正则表达式高整合度的优势。所以,为了能写出好的正则表达式,分析需要匹配的
文本(在这里就是url了)是必不可少的。

*************************************************************************************
我们常见的url无非是:aaa.bbb.ccc/123456789/........htm,gif等等
需要过滤的地址,由抽象到具体来说,往往有以下特点:

I.全部过滤一个不漏,只要出现就喀嚓,往往是令人深恶痛绝的url。
例(例子中都是用原始的带通配符的表达式):*.ad.*; */ad/*; *.3721.*/*或者*3721*
II.过滤网址主体,也就是第一个/号之前的所有。
例:www.1000downloads.com/*; www.w163.com/*
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|***|cjt1|w163|ppzxw|1000downloads)\.(net|com)
它等价于
http://*.***.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就知道了Smile

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的所有广告提供商……