The Adblock Project

The Adblock Project
――详解Adblock

什么是Adblock?
Adblock是一个配合Mozilla/Firebird浏览器(现在的Firefox浏览器)进行广告过滤的扩展程序。相对于浏览器内置的图像过滤而言,它更加强大和精确。
Adblock允许用户定义自己的过滤规则,并在规则基础上移除基于源地址的目标对象……听上去是不是很复杂?呵呵,别担心,事实并非如此,现在就让我们开始吧!

一、安装:
附带图片
首先,从 此处 获取Adblock。
安装并重新启动Firefox后,您会看到Adblock工具条已经出现在 工具菜单中。
附带图片
附带图片

二、使用:
只需加入很少的过滤规则,Adblock就会在载入网页时自动阻挡符合过滤条件的成分。看到了吗(上图),并不是那么困难!!
棒极了!……但是我应当 如何添加过滤规则呢?
A)可以从网页中添加。只需在广告图像上单击右键并选择 阻止图片(英文版则是 Adblock Image)。
附带图片
B)对于一些嵌入式媒体,Adblock标签(Adblock-tab,是一个半透明的标志,也叫物件标签Obj-Tabs)会出现在它们的顶部或底部,只需点击标签上的Adblock文字,即可将他们添加到Adblock过滤规则中。
附带图片 附带图片
附带图片
【注意:如果你遇到了一个嵌入式的媒体,而它的周围并没有显示Adblock标签(Adblock-tab),不要担心,Adblock标签只是被它挡住了(出现这种情况的原因可能是没有安装相应的插件)。从工具菜单中选择“ 置于Flash上”(左键单击)(英文版为 Overlay Flash)或直接使用快捷键(ctrl + shift + f),就可以直接在覆盖了Adblock-tab的图形上单击了。】
附带图片 附带图片
这样对付广告,方便多了吧。
C)双击已经选中的Adblock过滤规则(或者按回车键)可以编辑你的过滤规则。要去除某条过滤规则,按Delete键就可以了。新的过滤规则可以直接从这里增加:
附带图片
附带图片
Adblock支持两种类型的过滤规则:简易表示和正则表达式。
一条简易表示的过滤规则是由一行文字加上一个或多个通配符(目前仅支持*)组成的,而正则表示的过滤规则更为复杂,能够精确的控制过滤。在Adblock 中,如同所有的javascript一样,正则表示的过滤规则必须在开始和结束的时候加注斜杠(/)。我将在后文中详细介绍RegExp,如果你感兴趣,亦可 在此 获得更多相关讯息。
这里先给出一些简单的参考规则:
过滤所有的gif图像: *.gif
过滤所有来自doubleclick.net的内容 : doubleclick.net
过滤一个广告目录: http://example.com/ads/
(以上内容部分参考了 Adblock官方主页

三、一些提示:
1.善用列出可阻止元素功能
它十分强大(甚至可以用它来追踪Flash地址),对百度搜索等难以阻止的元素都有一定的作用。
附带图片
2.不要过多依赖简易表示
过分依赖简易表示不仅使规则变得冗杂,而且有可能导致误判。其实,如果善于使用正则表达式,Adblock要比其他浏览器自带的拦截工具强大得多。
3.哪里可以找到过滤规则
现成的过滤规则并不一定适合你,很可能会过滤一些正常信息。不过,如果你不像《六人行》中的莫尼卡那样坚决要求一个漏网之鱼都不能有的话,也有现成的:
这里有些现成的过滤文件
官方论坛
4.如何导入规则
参见高手篇中Adblock首选项的一些说明
5.如何设置不想屏蔽的广告
如果你是通过 阻止来自***的图片来阻止广告的,那么你此时使用的是Firefox内部的图片阻止程序,而不是Adblock!这个功能可以在 工具 > 选项 > 网页特性中进行设置,点击 载入图片复选框旁的 例外按钮,在弹出的对话框中,输入允许站点的网址,并确认没有选中 仅对原始站点复选框(除非你确实了解你在做什么)。
如果问题是由Adblock造成的,请期待Adblock的下个版本吧,届时将增加白名单功能。暂时可以通过以下两种方法解决问题:
a.再优化你的正则表达式
(首选。点击状态栏右下角的Adblock图标,在弹出的窗口中,被阻止的图片地址会显示为红色,选中它后会在下面的地址栏中显示出相应过滤规则。你也可以在 工具 > Adblock > 首选项中编辑或删除这个过滤规则。)
b.暂时关闭Adblock
(参见高手篇中Adblock首选项的一些说明)
6.Adblock为什么会让我的网页错位
你确定是Adblock造成的错位i?某些优化也会造成浏览错位的情况。试着暂时关闭Adblock并刷新页面,如果真的是由Adblock造成的,那可能是Adblock的移除广告造成的,换成隐藏广告试试。
说明:当选择隐藏广告时,被屏蔽的元素依然被下载到本地,只是不会显示而已;而移除广告则是不下载相应元素到本地,选中这个选项会重整页面,因而造成所谓的“错位”现象。
目前所发现的存在此问题的站点: 驱动之家
7.为什么我登陆不了某些网站(请先确定是Adblock造成的)
这是因为你在Adblock中选择了站点阻止。(参见高手篇中Adblock首选项的一些说明)
8.Adblock让我受够了,我不想再用他了,有没有替代他的软件
有的。可以试试Ad Muncher。
当然,也可以什么都不安装,Firefox本身就有很不错的广告拦截功能。
注意,这个规则太严格了,很多门户网站的标题文字链接都会被过滤掉,详情请见 此处

四、高级篇:
这里会介绍两点:一是正则表达式,二是Adblock菜单。
正如上面所介绍的那样,正则表达式具备很多优点,最有用的功能就是对付某些会动态改变的URL。举例来说,很多网站会根据日期显示不同广告,例如... /ad200410/...如果简单的屏蔽/ad*/,就有可能把一些例如/advance/...、/add/......之类正常、常用的URL给屏蔽了。而用正则表达式/ad(/d)*/就能精确的屏蔽掉ad后跟着若干数字的情况。
此外,如果你平时不怎么看Flash,可以添加简易规则*.swf。但是后果就是你无法登陆wallop,因为wallop的界面完全是由Flash构成的。你可以变通一下,将规则改为:/[^p](/.swf)/,这样对***p.swf形式的Fash就不会过滤啦。
怎么样,对正则表达式有些兴趣了吧。其实Adblock的正则表达式严格的遵循着正则表达式,之前一直奇怪为什么Adblcok不支持?功能,其实只是我表达方式的问题。关于正则表达式的内容可以参考 这里
要提高你表达正则表达式的水平,必要的练习是少不了的。在百度里搜搜 正则表达式练习器试试。
我们经常用到的一些正则规则式有:
字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

以下是关于正则表达式的一些补充,作者不是我,感谢Kmc提供。
QUOTE
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就知道了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的所有广告提供商……

下面就要介绍Adblock的菜单了:
A)列出所以可阻止的元素 ctrl+shift+A
单击Firefox右下角提示的Adblock链接也可以弹出它。
附带图片
附带图片
B)置于flash上(左键单击) ctrl+shift+F
详见使用说明,此处不再赘叙。
C)首选项 ctrl+shift+P
这可是最让人头疼的一章。一些内容的确不好懂。我把我所理解的一些东西写出来。大家共同探讨。
附带图片
检查父级链接:
先解释一下什么叫做 父级链接
Parent Links,好像也可以理解为目的地址(destination address)。例如:某个图片的地址是:http://www.abc.com/123.gif ,点击他后图片会指向:http://www.123.com/ 那么他的父级链接是这个http://www.123.com/
笼统的说,检查父级链接使Adblock去查找浏览网页中的 img / obj 的层次,寻找它们包含着的 "父级链接", 一旦被找到,他将与过滤条件核对url链接并阻止符合条件的元素。如果没有找到,Adblock将像没有选中检查父级链接一样的工作。
注意:检查父级链接能帮助你屏蔽掉一些广告文字链接,但是会影响你的浏览速度。
更详细的解释: http://aasted.org/adblock/viewtopic.php?t=23
站点阻止:
“站点阻止”将阻止符合过滤条件的站点。如果访问,你将得到一个空白页面(Adblock page)这个功能主要是用于挡住一些不适合儿童登录的站点。
比如你添加条件:http://www.163.com/* ,如果使用站点阻止,你进入163的主页时将得到一个空白页面。而如果没有选中,它只会过滤一些符合过滤条件的内容,你还是可以正常的访问163的。
对于导出/导入过滤的说明:
有人经常在论坛询问尝试着导入了从别处COPY下来的过滤规则,但遗憾的是,Adblock不认,这是怎么回事呀?其实Adblock有着严格的保存格式,如果不符合,就不导入。
其格式要求是:
导入的文件必须是纯文本文件(以.txt为扩展名),内容要求为:以[Adblock]作为第一行,表示他是一个过滤名单,注意大小写。然后一行一个过滤条件,不用其他的表示符号比如“url1=”什么的。(这里有人会奇怪为什么他的Adblock过滤条件对“?”不支持,很简单,因为不符合正则表达式啊(前面已经说了),在网址中不能直接用?代替,所以直接从遨游copy的过滤规则中,只要有?的,都无效啦。)
卸载:
和在扩展里删除Adblock的效果类似。后来Firefox的扩展管理功能做的很好,Adblock已经放弃了这个功能。注意Adblock的DeInstall卸载不干净,详细可参考官方论坛的讨论: 这里 这里
所以不建议你使用这个方法拆卸载扩展。

后期补充内容:
有些人反映adblock导入的规则不能保存,现在多说一句。
在adblock首选项中,无论是规则的更改、删除、导入,还是更改adblock选项,都必须在完成后点完成(英文版为Done),否则不会保存。很多人直接点标题栏中的×,是不保存更改的做法哦!
哪儿有正则表达式的练习器啊?
劳驾各位把你找到的练习器打包成RAR格式传上来吧,我也找不到。
软件站找到的练习器都需要到微软下载个Microsoft .NET Framework,不过是免费的啊。
这里再给几种方法把;
(被气死啦,中国建站专家写了片文章说是原创,但没说作者。我这里引用一下,如果那位作者认为我侵犯了他的版权,请发短信给我,我改!)
正则表达式练习测试页
前段时间差不多都要和正则表达式打交道,所以当时就弄了这个测试练习页面.把以下代码保存为一个HTML文件用IE打开即可使用:
(Sdog注:不能在firefox下运行)
QUOTE
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>正则表达式测试</title>
<style type="text/css">
<!--
td {
font-family: "宋体";
font-size: 12px;
color: #666666;
text-decoration: none;
}
input {
font-family: "宋体";
font-size: 12px;
color: #666666;
text-decoration: none;
border: 1px solid #000000;
height: 18px;
}
textarea {
font-family: "宋体";
border: 1px solid #333333;
word-spacing:inherit
}
.table {
font-family: "宋体";
font-size: 12px;
border: 1px solid #000000;
white-space: normal;
table-layout: fixed;
WORD-BREAK: break-all;
WORD-WRAP: break-word;
display: table;
}
.checkbox {
border: 1px dotted #CCCCCC;
}
-->
</style>
</head>

<body>
<table width="100%" height="306"  border="0" cellpadding="0" cellspacing="0">
<tr>
  <td valign="top"><div align="center">
    <table width="700"  border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td><div align="center">
          <textarea name="InputBox" cols="100" rows="20" id="InputBox"></textarea>
        </div></td>
      </tr>
    </table>
    <table width="700" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="1"></td>
      </tr>
    </table>
    <table width="722" border="0" cellpadding="0" cellspacing="1" class="table">
      <tr>
        <td height="25" bgcolor="#F2F2F2"><div align="center">正则表达式:
          <input name="RegExpBox" type="text" id="RegExpBox" size="100">
        </div></td>
      </tr>
    </table>
    <table width="700" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="1"></td>
      </tr>
    </table>   
    <table width="722" border="0" cellpadding="0" cellspacing="0" class="table">
      <tr>
        <td width="580" height="25" bgcolor="#F2F2F2"><div align="center">
  <input name="SingleLine" type="checkbox" class="checkbox" value="1">
        <span title="将更改(.)的意思,使它包含所有字符">单行模式查找</span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <input name="IgnoreCase" type="checkbox" class="checkbox" value="1">
        <span title="不区分字母的大小写">不区分大小写</span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
        <input name="Global" type="checkbox" class="checkbox" value="1">       
        <span title="查找所有的可匹配项">全局模式查找</span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;
        <input name="ShowSub" type="checkbox" class="checkbox" value="1">       
        <span title="只显示在()里面的记录集">只显示子记录集结果</span>
          </div></td>
        <td width="140" bgcolor="#F2F2F2"><input name="btnSearch" type="button" id="btnSearch" value="搜  索" onClick="vbscript:SearchRegExp()"></td>
      </tr>
    </table>
    <table width="700" border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td height="1"></td>
      </tr>
    </table>
    <table width="722" border="0" cellpadding="0" cellspacing="1" class="table">
      <tr>
        <td height="25" bgcolor="#FFFFCC"><div align="left" id="ShowText">
        </div></td>
        </tr>
    </table>
  </div></td>
</tr>
</table>
</body>
<script language="vbscript">
Function SearchRegExp()
Dim HTML,IgnoreCase,Global,Pattern,ShowSub
HTML = document.all.InputBox.value
Pattern = document.all.RegExpBox.value
If Trim(HTML) = "" Or IsNull(HTML) Or Pattern = "" Then
    document.all.ShowText.innerHTML = "<font color='red'>---------请输入要查找的文本---------</font>"
    Exit Function
End If
If document.all.SingleLine.checked Then
    HTML = Replace(HTML,VbCrlf,"")
End If
Global = document.all.Global.checked
IgnoreCase = document.all.IgnoreCase.checked
ShowSub = document.all.ShowSub.checked
Dim RegExpObj,RegMatch,I,II,SubMatch
Set RegExpObj = New RegExp
RegExpObj.IgnoreCase = IgnoreCase
RegExpObj.Global = Global
RegExpObj.Pattern = Pattern
Set RegMatch = RegExpObj.Execute(HTML)
If RegMatch.Count < 1 Then
    document.all.ShowText.innerHTML = "<font color='red'>---------共查找到0个记录---------</font>"
    Set RegMatch = Nothing
    Set RegExpObj = Nothing
    Exit Function
End If
document.all.ShowText.innerHTML = "<font color='red'>-----------------------查找开始--------------------< /font><br>"
Dim innerHTML
innerHTML = document.all.ShowText.innerHTML
For I = 0 To RegMatch.Count - 1
  Set SubMatch = RegMatch(I).SubMatches
  If Not ShowSub Then
    innerHTML = innerHTML + "<font color='red'>记录集" & I & ":</font><font color='blue'>" + HTMLEncode(RegMatch(I).Value) + "</font>"
  End If
  For II = 0 To SubMatch.Count - 1
        innerHTML = innerHTML + "<br><font color='#FF00FF'>" +HTMLEncode("    子记录") & II & ":</font>" + HTMLEncode(SubMatch(II))
  Next
  innerHTML = innerHTML + "<br><hr width=""100%"" size=""1"">"
Next
document.all.ShowText.innerHTML = innerHTML
Set RegMatch = Nothing
Set RegExpObj = Nothing
End Function
Function HTMLEncode(ByVal fString)
If Not IsNull(fString) then
fString = Replace(fString, ">", "&gt;")
fString = Replace(fString, "<", "&lt;")
fString = Replace(fString, " ", "&nbsp;")
fString = Replace(fString, CHR(32), "<I></I>&nbsp;")
fString = Replace(fString, CHR(9), "&nbsp;")
fString = Replace(fString, CHR(34), "&quot;")
fString = Replace(fString, CHR(39), "'")
fString = Replace(fString, CHR(13), "")
fString = Replace(fString, CHR(10) & CHR(10), "</P><P> ")
fString = Replace(fString, CHR(10), "<BR> ")
HTMLEncode = fString
Else
HTMLEncode=""
End If
End Function
</script>
</html>


这个也不错啦:作者已经在程序中注明:
正则表达式的用途很广泛,但要熟练掌握就不是一件容易的事情了。为此,我编写了这个练习器用来帮助学习。
请多指教!

QUOTE
*********将以下代码复制到 RegExp.htm 即可 **********
<HTML>
<HEAD>
<TITLE>正则表达式练习器</TITLE>
<meta name = 安徽 池州 统计局 徐祖宁 e-mail:czjsz@stats.gov.cn>
<script language="JavaScript">
function OnMove() {
window.status = "("+window.event.clientX+","+window.event.clientY+")" + " :: "+document.location
}
</script>

<script LANGUAGE="JavaScript1.2">
var re = new RegExp()  //建立正则表达式对象
var nextpoint = 0      //匹配时的偏移量
//设置正则表达式
function setPattern(form) {
var mode
if(form.chkmode.checked) mode = "gi"  //i:不分大小写 g:全局,好象没什么作用
else mode = "g"
re.compile(form.regexp.value,mode)
nextpoint = 0
form.reglist.value = ""
}
//检查是否有匹配
function findIt(form) {
setPattern(form)
var input = form.main.value
if (input.search(re) != -1) {
  form.output[0].checked = true 
} else {
  form.output[1].checked = true 
}
}
//检查匹配位置
function locateIt(form) {
setPattern(form)
var input = form.main.value
form.offset.value = input.search(re)
}
//检查所有的匹配情况
function execIt(form) {
if(nextpoint == 0 || ! form.scankmode.checked) {
  findIt(form)
  form.reglist.value = ""
}
var key = true
if(form.scankmode.checked) key = false
do {
  var input = form.main.value
  var matchArray = re.exec(input.substr(nextpoint))
  if(matchArray) {
    for(var i=1;i<matchArray.length;i++)
      matchArray = "$"+i+":"+matchArray
    form.reglist.value = (nextpoint+matchArray.index)+" => " + matchArray[0] +"n"+form.reglist.value
    form.matchlist.value = "$0:"+matchArray.join("n")
    nextpoint = nextpoint + matchArray.index + matchArray[0].length
  }else {
    if(!key)
      form.reglist.value = "没有找到n" + form.reglist.value
    form.matchlist.value = " "
    nextpoint = 0
    key = false
  }
}while (key)
}
//设置当前使用的正则表达式
function setregexp(n) {
var s = document.all.regexplist.value.split("rn")
document.all.regexp.value = s[n*2-1]  //.replace("r","")
nextpoint = 0
}

//定义选择监视
var isNav = (navigator.appName == "Netscape")
function showSelection() {
if (isNav) {
  var theText = document.getSelection()
} else {
  var theText = document.selection.createRange().text
}
if(theText.length>0 && document.all.selechkmode.checked)
  document.all.regexp.value = theText
}
if (isNav) {
  document.captureEvents(Event.MOUSEUP)
}
document.onmouseup = showSelection
</SCRIPT>

</HEAD>
<BODY style="font-size=9pt;" OnMouseMove=OnMove()>
<FORM><table width=100% cellspacing=0 cellpadding=0><tr><td><font color=red>正规表达式练习器</font></td><td align=right><a href=mailto:czjsz_ah@stats.gov.cn>czjsz_ah@stats.gov.cn</a></td></tr></table>
<table width=100% broder=1 frame=above rules=none style="font-size:9pt;">
<tr><td width=50%  valign=top>
输入一些被寻找的正文:<BR>
<TEXTAREA NAME="main" COLS=58 ROWS=5 WRAP="virtual" style="font-size:9pt;">
09-11-2001 09/11/2001 czjsz_ah@stats.gov.cn
asdff 12345 196.168.1.3 www.sohu.com ftp://www.chinaasp.com 2001.9.11 http://www.active.com.cn/club/bbs/bbsView.asp http://www.163.com/inden.htm
</TEXTAREA><BR>
进行匹配的正规表达式:  忽略大小写<INPUT TYPE="checkbox" NAME="chkmode" checked style="font-size:8pt;height:18px"><BR>
<TEXTAREA NAME="regexp" COLS=51 ROWS=5 style="font-size:9pt;"></TEXTAREA>
<INPUT TYPE="button" VALUE="清除" onClick="this.form.regexp.value=''" style="font-size:8pt;height:18px"><BR>
<INPUT TYPE="button" VALUE="能找到吗?[regexObject.test(string)]" style="font-size:8pt;width:70%;height:18px" onClick="findIt(this.form)">
<INPUT TYPE="radio" NAME="output" style="font-size:8pt;height:18px">Yes
<INPUT TYPE="radio" NAME="output" style="font-size:8pt;height:18px">No <BR>
<INPUT TYPE="button" VALUE="在哪里?[string.search(regexObject)]" style="font-size:8pt;width:70%;height:18px" onClick="locateIt(this.form)">
<INPUT TYPE="text" NAME="offset" SIZE=4 style="font-size:8pt;height:18px">
</td>
<td valign=top>
测试用正则表达式列表: 
使用第<input type=text name=num size=2 value=1 style="font-size:8pt;height:18px">个<input type=button value=Go onClick=setregexp(this.form.num.value) style="font-size:8pt;height:18px">
    允许复制<INPUT TYPE="checkbox" NAME="selechkmode" style="font-size:8pt;height:18px">
<textarea NAME="regexplist" cols=58 rows=14 wrap=off style="font-size:9pt;">
1.检查日期:
(1[0-2]|0?[1-9])[-./](0?[1-9]|[12][0-9]|3[01])[-./](dddd))
2.检查数字:
([-+]?[0-9]+.?[0-9]+)
3.检查URL:
((http|ftp)://)?(((([d]+.)+){3}[d]+(/[w./]+)?)|([a-z]w*((.w+)+){2,})([/][w.~]*)*)
4.检查E-mail
w+@((w+[.]?)+)
</textarea>
</td></tr>
<tr><td valign=bottom>
<INPUT TYPE="button" VALUE="有哪些?[regexObject.exec(string)]" style="font-size:8pt;width:70%;height:18px" onClick="execIt(this.form)">
  单步<INPUT TYPE="checkbox" NAME="scankmode" style="font-size:8pt;height:18px"><BR>
<TEXTAREA NAME="reglist" COLS=58 ROWS=8 style="font-size:9pt;"></TEXTAREA>
</td>
<td valign=bottom>
匹配到的成分:(单步时可见)
<TEXTAREA NAME="matchlist" COLS=58 ROWS=8 style="font-size:9pt;"></TEXTAREA>
</td></tr></table></FORM>
<script>
setregexp(1)
</script>
</BODY>
</HTML>


对正则表达式练习器的改进:(作者不详,估计就是上面的作者啦)
覆盖原execIt函数
修改后的execIt函数允许对多个正则表达式进行匹配(每个正则表达式一行),并对每一个匹配成分显示出是第几个正则表达式匹配的。
这可视为语法分析的雏形,只要对匹配产生相应的动作。

QUOTE
function execIt(form) {
var mode
if(form.chkmode.checked) mode = "gi"
else mode = "g"
var regexpArray = form.regexp.value.split("rn")  //获取正则表达式到数组

if(nextpoint == 0) form.reglist.value = ""
var key = true
if(form.scankmode.checked) key = false
else nextpoint = 0
do {
  var offs = 9999999999
  var pos = -1
  var input = form.main.value.substr(nextpoint)
  //对每个正则表达式进行匹配
  for(var i=0;i<regexpArray.length;i++) {
    re.compile(regexpArray,mode)
    var matchArray = re.exec(input)
    if(matchArray) {
      if(offs > matchArray.index) {
        offs = matchArray.index
        pos = i  //保存距离起始位子最近的匹配
      }
    }
  }
  if(pos>=0) {
    re.compile(regexpArray[pos],mode)
    var matchArray = re.exec(input)
    for(var i=1;i<matchArray.length;i++)
      matchArray = "$"+i+":"+matchArray
    form.reglist.value = "["+(pos+1)+"]"+(nextpoint+matchArray.index)+" => " + matchArray[0] +"n"+form.reglist.value
    form.matchlist.value = "$0:"+matchArray.join("n")
    nextpoint = nextpoint + matchArray.index + matchArray[0].length
  }else {
    if(!key)
      form.reglist.value = "没有找到n" + form.reglist.value
    form.matchlist.value = " "
    nextpoint = 0
    key = false
  }
}while(key)
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值