正则表达式基础笔记(一)

来源:互联网 发布:软件开发设计流程图 编辑:程序博客网 时间:2024/05/22 08:29

         由于项目的需求,使得我不得不学习正则表达式。前几天看了一个关于正则表达式方面挺好的文章,学习了一下,感觉讲的不错,所以就拿来与大家分享,但还是得花上几个小时来学习。文章地址如下: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+)这个子表达式当中括号为什么是必要滴呢?

       对于组名,我们可以进行指定,方法:(?<word>/w+)或者(?'word'/w+)这个时候会将分组(/w+)的组名指定为word。

      那如何引用指定的组名?    方法:可使用/k<word>

         如上边的那个例子可以改为:/b(?<word>/w+)/b/s+/k<word>/b

(21)常用分组语法

      这部分学的也不是太好,所以讲也是非常肤浅,只是我的一点感受而已,呵呵......现给大家列举出来,可以自己搜搜看。

      捕获:(exp)->匹配exp,并捕获文本到自动命名的组里。

               (?<name>exp)->匹配exp,并将捕获文本到名称为name的分组中,等价于:(?'name'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)->匹配前面不是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次或以上,但尽可能少。

       至此,笔记已经写完了,希望对你有帮助。