背景简介:
今天比较清闲,就看看电子书,又是看到有关正则表达式的资料。之前有整理过一篇正则表达式的语法,《(一) 正则表达式快速入手指南之字符集合表达式(包含个人总结)》,以及实战了CodeMirror自动提示功能的扩展。所以,对正则表达式的很多细节还是很迷糊的。既然看到了,那就整理整理吧。
简述:
正则表达式的语法不直观,而且书写规则出奇的复杂,因为它们把某些位置上的字符串解析为运算符,而把仅在位置上稍微不同的相同字符串当作字面量。比不易书写更糟糕的是,正则表达不直观,不易被直接理解,从而修改起来难度也比较高。一般,要正确的阅读正则式,需要对正则表达式的整个复杂性有相当彻底的了解。
但是,从相反的角度,正则表达式非常凝练,是处理字符串匹配的利器,因为可以避免使用逻辑代码处理字符串,从而具有很强的健壮性和扩展性。所以,掌握正则表达式成为程序员一项必备的技能。要熟练掌握这项技能,需要在实战中不断摸爬滚打,才能熟练使用这种高凝练的语言。
就像是查看复杂的代码块,我们需要一步步解析代码的含义。刚开始学习正则式,往往很难做到一眼看穿那么一大串看似杂乱的字符的含义。所以,欲穷千里目,只能放缓脚步,一步步查看,在平时积累一些常用的正则表达式。
案例1、URL匹配
首先,先说明URL的组成。URL是URI的一个子集,是UniformResource Locator的缩写,译为“统一资源定位符”。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL的格式主要由三部分组成:
1. 第一部分是协议
2. 第二部分是存有该资源的主机IP地址或者域名(有时候也会包括端口号)
3. 第三部分是主机资源的具体地址,如目录和文件名等
4. 第四部分是使用GET提交form,请求参数拼接在URL后面
其中,第一部分和第二部分用”://”符号隔开,第二部分和第三部分用“/”符号隔开,第三部分和第四部分用问号?分割,参数用&符号拼接键值对。第一部分和第二部分是不可缺少的,第三、四部分有时候可以忽略。比如:
① http://www.baidu.com —— 没有指定端口号和第三部分
② http://blog.csdn.net/wendingzhulu/article/details/38168039—— 指定第三部分
如何写这个URL的正则表达式呢,就根据这四部分进行编写。每个部分都对应到一个正则表达式分组上。
1. 匹配协议,协议主要有http/https/file等,简单点归纳为由英文字母拼接而成(不一定正确)。那么如下表示
^(?:([A-Za-z]+)){1}
详解:其中^指明字符串匹配的起始点,A-Za-z表示所有大小写英文字符,在中括号内,[A-Za-z]表示任意一个英文字符;后面的+号是量词,[A-Za-z]+表示至少有一个英文字符。然后是小括号,表示分组。分组这个概念之前没有详述,可以参考《正则表达式的分组》(http://www.cnblogs.com/symbol441/articles/957950.html),主要是为了解决重复性字符串定义。接下来对这个分组限定,使用(?:pattern)表示不捕获匹配的子表达式——具体是什么意思,也不是很清楚,待以后考究。然后{1}指定这个组有且仅有一次匹配。
2. 第一和第二部分的衔接
(:\/{2}) /转义,表示\要被匹配2次即://
3. 第二部分,主机名正则式
([0-9.\-A-Za-z]+),中括号内表示字符范围,+表示匹配1次以上,这个分组即表示主机名由一个或多个数字、字母或.或-组成(PS:这个匹配式比较粗犷,不一定准确)。
4. 端口号
(?::(\d+))? 这个比较简单,不做解释
5. 第三部分,具体的目录或者文件路径,可以为空
(?:\/([^?#]*))?
该分组以一个/开始,分组([^?#]*)中^指除?#之外的所有字符(PS:这里也不一定准确),*表示匹配0次或多次(.*可以表示匹配除换行符以为的所有字符)。
6. 第四部分,匹配查询语句——这是我自己写的,不一定准确
\?(([0-9.\-A-Za-z]+)=(\S*)&{0,1})?
匹配从?开始,然后格式是key1=value1&key2=value2这样的形式,做了一下在线测试,当前满足要求
把上面所有的连接在一起,得到结果为
^(?:([A-Za-z]+)){1}(:\/{2})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(\?(([0-9.\-A-Za-z]+)=(\S*)&{0,1})+)?$
匹配结果如下
案例2
待续...
小结:
写写博客,做一下总结
参考资料:
正则表达式语法:http://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx
正则表达式分组、断言详解:http://www.cnblogs.com/iyangyuan/archive/2013/05/30/3107390.html