1、重写 url必须掌握正则表达式 url 重写2008-07-20 12:00http:/ 简单的说,正则表达式是一种可以用于模式匹配和替换的强有力的工具。我们可以在几乎所有的基于 UNIX系统的工具中找到正则表达式的身影,例如,vi 编辑器,Perl 或 PHP脚本语言,以及 awk或 sed shell程序等。此外,象 JavaScript这种客户端的脚本语言也提供了对正则表达式的支持。由此可见,正则表达式已经超出了某种语言或某个系统的局限,成为人们广为接受的概念和功能。 正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模式与数据文件、程序输入以及 WEB页面的表单输入等
2、目标对象进行比较,根据比较对象中是否包含匹配模式,执行相应的程序。 举例来说,正则表达式的一个最为普遍的应用就是用于验证用户在线输入的邮件地址的格式是否正确。如果通过正则表达式验证用户邮件地址的格式正确,用户所填写的表单信息将会被正常处理;反之,如果用户输入的邮件地址与正则表达的模式不匹配,将会弹出提示信息,要求用户重新输入正确的邮件地址。由此可见正则表达式在 WEB应用的逻辑判断中具有举足轻重的作用。基本语法 在对正则表达式的功能和作用有了初步的了解之后,我们就来具体看一下正则表达式的语法格式。 正则表达式的形式一般如下: /love/ 其中位于“/”定界符之间的部分就是将要在目标对象中进行
3、匹配的模式。用户只要把希望查找匹配对象的模式内容放入“/”定界符之间即可。为了能够使用户更加灵活的定制模式内容,正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。较为常用的元字符包括: “+”, “*”,以及 “?”。其中,“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次,“*”元字符规定其前导字符必须在目标对象中出现零次或连续多次,而“?”元字符规定其前导对象必须在目标对象中连续出现零次或一次。 下面,就让我们来看一下正则表达式元字符的具体应用。 /fo+/ 因为上述
4、正则表达式中包含“+”元字符,表示可以与目标对象中的 “fool”, “fo”, 或者 “football”等在字母 f后面连续出现一个或多个字母 o的字符串相匹配。 /eg*/ 因为上述正则表达式中包含“*”元字符,表示可以与目标对象中的 “easy”, “ego”, 或者 “egg”等在字母 e后面连续出现零个或多个字母 g的字符串相匹配。 /Wil?/ 因为上述正则表达式中包含“?”元字符,表示可以与目标对象中的 “Win”, 或者 “Wilson”,等在字母 i后面连续出现零个或一个字母 l的字符串相匹配。 除了元字符之外,用户还可以精确指定模式在匹配对象中出现的频率。例如, /jim
5、2,6/ 上述正则表达式规定字符 m可以在匹配对象中连续出现 2-6次,因此,上述正则表达式可以同 jimmy或 jimmmmmy等字符串相匹配。 在对如何使用正则表达式有了初步了解之后,我们来看一下其它几个重要的元字符的使用方式。 s:用于匹配单个空格符,包括 tab键和换行符; S:用于匹配除单个空格符之外的所有字符; d:用于匹配从 0到 9的数字; w:用于匹配字母,数字或下划线字符; W:用于匹配所有与w 不匹配的字符; . :用于匹配除换行符之外的所有字符。 (说明:我们可以把s 和S 以及w 和W 看作互为逆运算) 下面,我们就通过实例看一下如何在正则表达式中使用上述元字符。 /
6、s+/ 上述正则表达式可以用于匹配目标对象中的一个或多个空格字符。 /d000/ 如果我们手中有一份复杂的财务报表,那么我们可以通过上述正则表达式轻而易举的查找到所有总额达千元的款项。 除了我们以上所介绍的元字符之外,正则表达式中还具有另外一种较为独特的专用字符,即定位符。定位符用于规定匹配模式在目标对象中的出现位置。 较为常用的定位符包括: “”, “$”, “b” 以及 “B”。其中,“”定位符规定匹配模式必须出现在目标字符串的开头,“$”定位符规定匹配模式必须出现在目标对象的结尾,b 定位符规定匹配模式必须出现在目标字符串的开头或结尾的两个边界之一,而“B”定位符则规定匹配对象必须位于目
7、标字符串的开头和结尾两个边界之内,即匹配对象既不能作为目标字符串的开头,也不能作为目标字符串的结尾。同样,我们也可以把“”和“$”以及“b”和“B”看作是互为逆运算的两组定位符。举例来说: /hell/ 因为上述正则表达式中包含“”定位符,所以可以与目标对象中以 “hell”, “hello”或 “hellhound”开头的字符串相匹配。 /ar$/ 因为上述正则表达式中包含“$”定位符,所以可以与目标对象中以 “car”, “bar”或 “ar” 结尾的字符串相匹配。 /bbom/ 因为上述正则表达式模式以“b”定位符开头,所以可以与目标对象中以 “bomb”, 或 “bom”开头的字符串相
8、匹配。 /manb/ 因为上述正则表达式模式以“b”定位符结尾,所以可以与目标对象中以 “human”, “woman”或 “man”结尾的字符串相匹配。 为了能够方便用户更加灵活的设定匹配模式,正则表达式允许使用者在匹配模式中指定某一个范围而不局限于具体的字符。例如: /A-Z/ 上述正则表达式将会与从 A到 Z范围内任何一个大写字母相匹配。 /a-z/ 上述正则表达式将会与从 a到 z范围内任何一个小写字母相匹配。 /0-9/ 上述正则表达式将会与从 0到 9范围内任何一个数字相匹配。 /(a-zA-Z0-9)+/ 上述正则表达式将会与任何由字母和数字组成的字符串,如 “aB0” 等相匹配
9、。这里需要提醒用户注意的一点就是可以在正则表达式中使用 “()” 把字符串组合在一起。“()”符号包含的内容必须同时出现在目标对象中。因此,上述正则表达式将无法与诸如 “abc”等的字符串匹配,因为“abc”中的最后一个字符为字母而非数字。 如果我们希望在正则表达式中实现类似编程逻辑中的“或”运算,在多个不同的模式中任选一个进行匹配的话,可以使用管道符 “|”。例如: /to|too|2/ 上述正则表达式将会与目标对象中的 “to”, “too”, 或 “2” 相匹配。 正则表达式中还有一个较为常用的运算符,即否定符 “”。与我们前文所介绍的定位符 “” 不同,否定符 “”规定目标对象中不能存
10、在模式中所规定的字符串。例如: /A-C/ 上述字符串将会与目标对象中除 A,B,和 C之外的任何字符相匹配。一般来说,当“”出现在 “”内时就被视做否定运算符;而当“”位于“”之外,或没有“”时,则应当被视做定位符。 最后,当用户需要在正则表达式的模式中加入元字符,并查找其匹配对象时,可以使用转义符“”。例如: /Th*/ 上述正则表达式将会与目标对象中的“Th*”而非“The”等相匹配。使用实例在对正则表达式有了较为全面的了解之后,我们就来看一下如何在 Perl,PHP,以及 JavaScript中使用正则表达式。通常,Perl 中正则表达式的使用格式如下:operator / regul
11、ar-expression / string-to-replace / modifiers运算符一项可以是 m或 s,分别代表匹配运算和替换运算。其中,正则表达式一项是将要进行匹配或替换操作的模式,可以由任意字符,元字符,或定位符等组成。替换字符串一项是使用 s运算符时,对查找到的模式匹配对象进行替换的字符串。最后的参数项用来控制不同的匹配或替换方式。例如:s/geed/good/将会在目标对象中查找第一个出现的 geed字串,并将其替换为 good。如果我们希望在目标对象的全局范围内执行多次查找替换操作的话,可以使用参数 “g”,即 s/love/lust/g。此外,如果我们不需要限制匹配的
12、大小写形式的话,可以使用参数 “i ”。例如,m/JewEL/i上述正则表达式将会与目标对象中的 jewel,Jewel,或 JEWEL相匹配。在 Perl中,使用专门的运算符“=”指定正则表达式的匹配对象。例如:$flag = s/abc/ABC/上述正则表达式将会把变量$flag 中的字串 abc替换为 ABC。下面,我们就在 Perl程序中加入正则表达式,验证用户邮件地址格式的有效性。代码如下:#!/usr/bin/perl # get input print “Whats your email address?n”; $email = chomp($email); # match an
13、d display result if($email = /(a-zA-Z0-9_-)+(a-zA-Z0-9_-)+(.a-zA-Z0-9_-)+/) print(“Your email address is correct!n”); else print(“Please try again!n”); 如果用户更偏爱 PHP的话,可以使用 ereg()函数进行模式匹配操作。ereg()函数的使用格式如下: ereg(pattern, string)其中,pattern 代表正则表达式的模式,而 string则是执行查找替换操作的目标对象。同样是验证邮件地址,使用 PHP编写的程序代码如下:最后
14、,我们在来看一下 JavaScript。JavaScript 1.2 中带有一个功能强大的 RegExp()对象,可以用来进行正则表达式的匹配操作。其中的 test()方法可以检验目标对象中是否包含匹配模式,并相应的返回 true或 false。我们可以使用 JavaScript编写以下脚本,验证用户输入的邮件地址的有效性。URL 重写可删节日期模式-正则表达式之强力应用 最近忙着自己的博客程式,自然而然就转到了博客中老生长谈的 URL 重写问题。一个原因是在多用户博客系统中的一个面子问题,本来想拿我的 CSDN 博客http:/ 来说事,想想还是用我的空间(http:/)吧,因为这是我的博客
15、完功之后的去所了。像 http:/ 如若不进行必要的 URL 重写,就会出http:/ 样子的博客地址;大家要知道BLOG 可谓是大部分网民视为筑在网络上的另一个家,现实生活中会考虑家的地址远近,交通好坏,同样网络中的家也要有个好记的门牌号的。这个门牌号还不算太长(还不是非常体面哦),后边在加上一堆的参数只怕让人慢慢见而生畏,要看文章就要面对这么一大堆http:/ URL 传值了。这就是重写他的原因了。主角又要出场了:正则表达式。在这里用正则表达式真的是太帅了 http:/ 目录你可能会生成如下这样的 URL 重写规则:/(w6,16)/Articles/(d4)/(d2)/(d2)/Defa
16、ult.aspx/Default.aspx?Bloger=$1year=$2month=$3day=$4这样写出的规则在进行删节时肯定是会因为访问的页面不存在而产生 404 错误。因为他会顺着你的目录标记一直往下找,要是再建目录工程可就大了,再看看下边的代码:/(w6,16)/Articles/(d4)/(d2)/(d2)/(d6)/Default.aspx/Default.aspx?Bloger=$1year=$2month=$3day=$4time=$5这下多出了时间部分该没人会选择建目录了。那就充分利用已存在的文件来完成这个任务吧。其实一说可能有非常多人都能想到用文件名来代替目录结构。想
17、想看,是不是这样。当然这还得对正则表达式有一定的了解。好,来看看实现吧。/(w5,16)/Articles/(d4)/(d2)/(d2)/(d6).aspx/Default.aspx?ArticleID=$2$3$4$5Bloger=$1大家非常容易看出我这里用到了“” 对“/”进行了转义,而且用在了文件名里边目前的结构就是 http:/ ArticleID 就是个以年月日时分秒为基础的字符串,因为这样插入数据不用考虑重复更有意义,而在这里用时间也为查询时方便。$2$3$4$5 得到的 14 位组合就是我的ArticleID.通过发表日期,文章编号都能非常容易查出记录。而最后一点好处就在进行删
18、节时表现的特为明显。目前来让我们删节时间部分:/(w5,16)/Articles/(d4)/(d2)/(d2).aspx/Default.aspx?ArticleID=$2$3$4Bloger=$1依次我们能将 URL 删节为这样的模式: http:/ http:/ 和http:/ 有什么差别,做到上边的规则后后者能否正常运行?不能同样:http:/ 也是不行的。还需要定义其他应对规则来实现恰如其份的重写效果。好了,大致上效果已出来了;这里是完整的规则代码:/(A-Za-zw5,16)/Default.aspx/Default.aspx?Bloger=$1/Articles/(d4)/(d2)
19、/(d2)/(d1,6)/(A-Za-zw5,16).aspx/Default.aspx?ArticleID=$1$2$3$4Bloger=$5/Articles/(d4)/(d2)/(d2)/(d1,6)(/)?).aspx/Default.aspx?ArticleID=$1$2$3$4/Articles/(d4)/(d2)/(d2)/(A-Za-zw5,16).aspx/Default.aspx?ArticleID=$1$2$3Bloger=$4/Articles/(d4)/(d2)/(d2)(/)?).aspx/Default.aspx?ArticleID=$1$2$3/Articles
20、/(d4)/(d2)/(A-Za-zw5,16).aspx/Default.aspx?ArticleID=$1$2Bloger=$3/Articles/(d4)/(d2)(/)?).aspx/Default.aspx?ArticleID=$1$2/Articles/(d4)/(A-Za-zw5,16).aspx/Default.aspx?ArticleID=$1Bloger=$2/Articles/(d4)(/)?).aspx/Default.aspx?ArticleID=$1/Articles/(A-Za-zw5,16).aspx/Default.aspx?Bloger=$1/Article
21、s/Default.aspx/Default.aspx?ArticleID=-1说明:在这里为了访止用户误删节掉重要的.aspx 扩展名,我将用户名作为了文件的虚拟标识名称。最后得到的 URL: http:/ 6 位的时间设置为可删节变长,就算丢了某些数字也能最方便的找到和该发表时间最接近的列表。在去除用户名后也不会影响到使用,还是通过前边周详的时间格式非常快会得到和你需要的文章最批配的列表。如果用户名完好则能通过删节找到特定时间段对应作者的文章列表。还要注意的是:用户名的格式(A-Za-z6-16)和规则验证的顺序。总结:通过规则的 URL 重写过程后像实际存在此目录相同会具有严密的格式但显得框架结构更方便更灵活,从而得到功能和用户体验上的重点提升暂时到这里吧。有什么疑问欢迎回复加入讨论。如果有更好的重写方法非常高兴能通知下本人哦。