由于项目的需求,使得我不得不学习正则表达式。前几天看了一个关于正则表达式方面挺好的文章,学习了一下,感觉讲的不错,所以就拿来与大家分享,但还是得花上几个小时来学习。文章地址如下:http://wenku.baidu.com/view/7f2c10791711cc7931b7163f.html。 我自己也写了一些笔记与大家分享,希望自己顺便记一下,也让各位顺便能快速的浏览一下他基本的内容。
(1) /b ------代表单词的开头或结尾,也就是单词的分界处。
(2) . ------代表除换行符以外的任意字符。
(3) * ------代表它之前的内容可以连续重复使用任意次以上使整个表达式匹配,可以是0次,1次 或多次。
(4) /d ------匹配一位数字。
(5) /s ------匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。
(6) /w ------匹配字母、数字、下划线或数字。
(7) + ------匹配1个或多个连续的字符。
(8) ^ ------匹配字符串的开始。
(9) $ ------匹配字符串的结束。
(10)字符转义------可使用/来取消某些字符的特殊意义,如/.和/*。
(11) ? ------前边的那个单位的东西重复0次或1次,注意是最靠近?那个单位的东西,可能只是一个字符,亦可能是一个分组的字符串,关于分组可以参考18条。
(12) {n} ------ 前边的那个单位的东西 重复n次。
(13) {n,} ------ 前边的那个单位的东西 重复n次或更多次。
(14) {n,m} ------ 前边的那个单位的东西 重复n到m次。
(15) [abc123] ------匹配指定的任意一个字符,我这里写的abc
(16) | 分支条件 ------有若干条规则,若满足其中任意一种规则都应当匹配,具体方法是用|将不同的规则分开。
至此,一些基本的都已经介绍完毕,我们举几个例子,使用之前的东西,你可能会更加的清楚明白:
/(?0/d{2}[) -]?/d{8}
怎么样,感觉上边的例子给力吗,呵呵...只要一个个分析,还是挺简单的。
/(代表转义字符,转义为(,为何不直接写(而要用个转义的方式呢,因为(还有别的用途,这个后边还会解释。如果你直接写个(,计算机可能并不会把它当做字面的(括号来使用,不知道这样解释能清楚么。
接下来是个?,这个大家对照第11条可以知道,它代表之前的那(可出现或不出现。
之后是0.
然后出现转义字符/d,代表数字。
之后是{2}代表前边的/d出现两次,即两位数字。
之后是 [) -],参考15条,它可以是)、 、-中的任意一个字符
尔后的?应该知道什么意思了吧。
之后是/d{8}代表匹配8位数字。
这个正则表达式的匹配情况如附图所示
从图中看到,对于第3和第4个,我们并不是非常的建议,因为它并不符合实际的要求,此时,我们的第16条派上了用场,更好的正则表达式(但并不完全,期望读者自己实践一下)如下:
/(0/d{2}/)/d{8}|0/d{2}[-]?/d{8}
其实,是有一些工具可以用来验证我们写的正则表达式是否正确,我给我的资源里边传了一个,你们可以搜索下来进行使用,这个工具非常好用,强烈建议!!!!!!
(17) /d{5}-/d{4}|/d{5}------用于匹配美国邮政代码的例子,闪光点:这两个分支条件是否可以互换。
答案为否了。若换成/d{5}|/d{5}-/d{4}的话,那它只会匹配5位邮编和9位邮编的前5位,期望你能理解。即匹配分支条件的时候,将会从左到右的测试每个条件,知道满足了某分支之后跳出。这提醒我们,对于分支条件,要注意顺序。
(18) 分组 ------用小括号指定子表达式,即分组。下边给个匹配IP的例子,自己可以研究一下:
((2[0-4]/d25[0-5]|[01]?/d?/d)/.){3}(2[0-4]/d|25[0-5]|[01]?/d?/d)
从上边这个例子我们可以看到,分组的目的就是要形成一个单位。
(19) 反义 ------查找不属于某个能简单定义字符类的字符
/W 匹配任意不是字母,数字,下划线或汉子的字符。
/S 匹配任意不是空白符的字符
/D 匹配任意不是数字的字符
/B 匹配不是单词开头或结束的位置
[^x] 匹配出了x以外的任意字符
[^aeiou] 匹配出了aeiou几个字母外的任意字符
(20) 后向引用 ------用于重复搜索前面某个分组匹配的文本
每个分组都会拥有一个组号,规则是从左到右,以左括号为标志,分别命名为1,2,3...
例如:/b(/w+)/b/s+/1/b用来匹配重复的单词,注意,只用来匹配重复一次的单词
如该正则表达式匹配 go go go,则匹配结果是go go。
思考:若要匹配出现任意次的正则表达式应当如何写呢?下边给出笔者的一个思路
(/b(/w+)/b/s*)*/2/b 注意:对于(/w+)这个子表达式当中括号为什么是必要滴呢?
对于组名,我们可以进行指定,方法:(?
那如何引用指定的组名? 方法:可使用/k
如上边的那个例子可以改为:/b(?
(21)常用分组语法
这部分学的也不是太好,所以讲也是非常肤浅,只是我的一点感受而已,呵呵......现给大家列举出来,可以自己搜搜看。
捕获:(exp)->匹配exp,并捕获文本到自动命名的组里。
(?
(?:exp)->匹配exp,但是不捕获匹配。
零宽断言:(?=exp)->匹配exp前面的位置。如:
/b/w+(?=ing/b) 对该例子分析,我们知道它匹配这样的一个字符串,该字 符串为结尾是ing的单词的前半部分。如:They are singing !匹配的结果是sing。
闪光点:为什么匹配的结果不是s?对,因为/b的存在。但是,如果将最后的那个/b去掉的话,同样匹配的结果是sing,为什么呢?这涉及到正则表达式的贪婪特性,请再接再厉看完吧,嘿嘿...
(?<=exp) ->匹配exp后面的位置。如:
(?<=/bre)/w+/b 该表达式匹配以re开头的单词的后半部分。
(?!exp)->匹配后面跟的不是exp的位置。
(?匹配前面不是exp的位置。
注释: (?#comment) ->只是用于提供注释。
(22)贪婪与懒惰
当正则表达式当中包含可能接受重复的限定符时,通常是匹配尽可能多的字符,这称为贪婪匹配。
例如:a.*b 匹配字符串 aabab的结果是aabab。
当然,正则表达式也有想发懒的时候,即它想要匹配尽量少的字符,这称为懒惰行为。此时只要加一个?即可。
例如:a.*?b 匹配字符串aabab的结果是aab和ab。
然而,你有没想过,上边的懒惰匹配结果为什么不是ab和ab呢?这因为正则表达式还有一条规则,比贪婪与懒惰行为的优先级更高:最先开始的匹配拥有最高的优先权,The match that begins earliest wins.
懒惰行为的限定符有如下这些:
*?->重复任意次,但尽可能少的重复。
+?->重复一次或多次,但尽可能少的重复。
?? ->重复0次或1次,但尽可能匹配重复1次的。
{n,m}?->重复n次到m次,但尽可能少的重复。
{n,}? ->重复n次或以上,但尽可能少。
至此,笔记已经写完了,希望对你有帮助。