正则表达式概念详解

原创 2016年05月30日 15:28:26
正则表达式就是使用一些抽象出来用来代表某类字符的特定字符组成的字符串。
正则表达式是用来在大量字符中匹配(寻找)符合自身字符规则的字符串。

正则表达式是一种规则(人为定义的用某些字符表示一类字符的规则)。
下面主要说明定义正则表达式规则所抽象出来的所有字符所包含的意义。


1. 元字符
            

    .      匹配除了换行符以外的任意字符                            
                  ....    -->   asdf
    \w   匹配字母、数字、下划线、汉字                              
                \w\w\w\w    -->    a3_我      
    \s    匹配任意空白符(空格,换行,制表符)                 
    \d    匹配所有数字                                                         
                \d\d\d\d    -->    1234
    \b    匹配单词的开始或结束                                            
                \bhi\b  在文本asdfawef hi asdfwz中会匹配hi,在文本dsfgsdfgsdfghidsfgsdfgsd不会匹配其中的hi单词,即\b要匹配一个单词的起始位置,起始位置必须是各种空白符,但是\b单独不匹配空白符,有单词才匹配空白符。如果使用\b\b测试,不会匹配任何字符。
    ^     匹配字符串的开始                                               
               ^用来查看字符串的开始位置是否有符合目标的,^hi 在文本hisdafsdfawsef中可以匹配hi,但是在文本sadfasdfhiasdfsad、 hiasdfasdfasdf(第一个是空格)中都不会匹配任何字符,如果是在多行模式下,换行符相当于字符串的结束位置。
    $      匹配字符串的结束           
                $用来查看字符串的末尾是否有符合标准的, $hi 在文本asdfasefashi中匹配hi,但在文本asdfawefasdhiasdfas、fasdfasdffasdahi (最后一个是空格)不会匹配任何字符,如果是在多行模式下,换行符相当于字符串的结束位置。               

2. 字符转义
    正则表达式规则定义了一些具有意义的字符,如果想使用正则表达式匹配这些特定字符就需要使用转义的方式,就是在 这些字符的前面加上一个反斜杠。
    \* 匹配 *,  \. 匹配 ., 如果要匹配\,也要使用转义 \\ 

3. 重复
            

    *      重复0次或多次
        .*  代表任意字符重复0次或者多次,可以匹配  dsfasdfadasd、fase、(什么也没有)
    +     重复1次或多次
        .+ 代表任意字符重复1次或者多次,可以匹配  dsfasdfadasd、fase
    ?    重复0次或1次
        .?  代表任意字符重复0次或者1次,可以匹配  a、1、_、(什么也没有)
    {n}    重复n次
        .{5}   代表任意字符重复5次,可以匹配  asdfa、s des、122 4、     (五个空格)
    {n,}   重复n次或n次以上,注意括号中逗号后面是没有空格的
        .{5,}    代表任意字符重复5次或者5次以上,可以匹配  fassd、fsdafsdfasdf、fasdfasdf sdf2we      
    {n,m}  重复n到m次。
        .{5,10}   代表任意字符重复5到10次,包含10次,可以匹配  dasfasdf、sddwe、xzczcwesdv

4. 字符集
    使用中括号 [] 把一些字符括起来组成一个字符集。
    [aeiou]  匹配   sdfwaefdaxdfawefiousdfiuo
    [+*-?!$^.]   这些符号都可以匹配到并且不用转义, 在字符集中只有 \ 需要使用转义,其他字符都不需要     fa.sdfas+-asdf*asdfgsa$sd^asdfgs?sdgfa
    [1-9]  - 号还可以当做表示一个范围的符号(只有在字符集中且前面的字符编码比后面的字符编码小才可以,前大后小会出错)。 23678532813zxd23wedfas   不匹配0
    [\\]  转义之后才可以匹配 \                 asdefasdasfedf\asdfaw\asdfx\sd    
    由以上的例子可以看出,字符集就是用来查找某一个位置的字符是否符合字符集中的某个字符。
            注: 字符集中 ^ 这个符号在第一位和其他位置的意义不同,在其他位置才代表匹配^号,在第一位的情况会在 第6 节反义 里面说明。

5. 分支
    使用  |  符号可以实现    的意义。
    \d{5}-\d{4}|\d{5}   匹配  5位数字-4位数字 或者 5位数字 -->  11111-1111 或者 11111  
    \d{5}|\d{5}-\d{4}   匹配  5位数字 或者 5位数字-4位数字 -->  11111 或者 11111-1111
    但是要注意的是,第二个表达式不会匹配到或后面的形式,因为正则表达式的或语句在查找的时候是从左到右进行对比的,如果前面的匹配就不会在查看后面的了。也就是说,使用第二个表达式,如果有11111-1111的形式,由于前面5个1已经符合了或前面的形式,故只会查找出来前五位组成11111。


6. 反义
                

   \W    匹配除字母、数字、下划线、汉字以外的字符
    \S       匹配除了空白符意外的字符
    \D      匹配除了数字意外的字符
    \B       匹配不是单词开头和结束的位置 
        以上4个使用符号没什么大的变化就不举例说明了。
    [^x]    匹配除了x之外的任意字符
    [^wasd]    匹配除了wasd之外的任意字符
        使用字符集定义反义的这种方式一定要注意的是  ^这个符号必须在字符集的第一位,且该符号后面有一个任意符号才可以生效,匹配除了^后面所有的符号之外的符号。
    例如:
        [^asdfawef++!!@_]  这种就是除了asdfawef++!!@_之外的任意符号
        [sdfasdf^awef]  而这种只是一个字符集而已

7. 分组
    通过 第三节重复 我们已经掌握了对单个字符重复的方法,但是如何对多个字符进行重复呢?
    使用 () 小括号将需要整体重复的部分括起来之后使用 之前说的重复方法进行重复的设置即可。
    (\d{5}-\d{4}|\d{5}){2}   这个式子将 11111-1111或者11111 这种形式重复了两次   12345-678912345-678912312,1231234121234。

                
    每次使用一对 () 小括号,就是分了一个组,这个组的内容就是括号里面的正则表达式,并且要注意的是每个组都有一个组号(编号),这个组号是自动分配的,分配原则是:
    1. 从左到右分配组号,第一个组是1,依次类推。(正则表达式整体是一个组,组号是0)
    2. 实际上会从左到右查找两次,第一次给未命名的组分配组号,第二次给已命名的组分配组号。
    3. 可以使用(?:xxx)的语法来让一个组不参与自动分配组号。
    下面的后向引用、零宽断言、负向零宽断言、注释都是对 () 的使用技巧。也就是分组的使用技巧

8. 后向引用
   后向引用是指通过  反斜杠\ 加上 数字(组号)的方式来重复使用某一组的正则表达式。
    例如:  (\d+)\s{1}\1   这个式子中可看出 \d+ 是第1组,组号就是1,后面的\1就是引用了前面这一组的内容,相当于 (\d+)\s{1}(\d+)。用于匹配一些数字中
间有一个空白符之后又是一些数字的形式。
                \b(\w+)\b\s+\1\b   同样这个式子中  \w+ 是第一组,组号是1,后面使用了\1的方式引用了前面的内容。用于匹配 go go 、hello hello 这种形式。
     还有一种情况是某一组如果通过(?<name>exp)这样的语法设置了一个名字,可以通过上面说的方法引用,还可以使用 \k<name> 这样的方法引用该表达式。例如:\b(\w+)\b\s+\1\b  也可以写成  \b(?<Word>\w+)\b\s+\k<Word>\b
     最后,我们还可以使用(?:exp)这样的语法使一个组得不到组号。
     注: 要使用 后向引用 一定要对要引用的那个组的组号很清楚。

9. 零宽断言
    零宽断言有两种: 
        1. 零宽度正预测先行断言 (?=exp)
                这个语法能断言自身出现的位置的后面能匹配到exp表达式,最后输出结果不包括exp匹配的字符
                例如: \b\w+(?=ing\b 这个式子用来匹配 以ing结尾的单词,但不包含ing dsfasfaasd wsding sadfa aoweing asdaing 
        2. 零宽度正回顾后发断言 (?<=exp)
            这个语法能断言自身出现的位置的前面能匹配到exp表达式,同样最后输出的结果不包含exp匹配的字符  
               例如: (?<=\bre)\w+\b  这个式子用来匹配 以 re 开头的单词,但不包含re      sfafalinn resadfasil klkjresafdssj

10. 负向零宽断言
    负向零宽断言也有两种: 
        1. 零宽度负预测先行断言 (?!exp)
                这个语法能断言自身出现的位置后面不能匹配exp表达式
                例如:\d{3}(?!\d)  匹配三位数字,并且这三位数字后面不能是数字    hkhkh123hkkbjkb4353jkhh213
        2. 零宽度负回顾后发断言 (?<!exp)
                这个语法能断言自身出现的位置前面不能匹配exp表达式
                例如:(?<![a-z])\d{7} 匹配前面不是小写字母的七位数字 asdkfhlkh123123412hkhASEDAK131241231
        举例:(?<=<(\w+)>).*(?=<\/\1>)   能匹配两个标签之间的内容   <b>asdfaweasdfasdfs</b>

11. 注释
    使用(?#comment)这种语法可以给表达式添加注释,是阅读变得容易一点。
        例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)
    还有一种使用注释的方法,就是启用“忽略空白”模式,在此模式下所有空白被忽略,并且启动使用#的注释方法。此模式下#后面的到这一行结束的所有文本都会被当做注释:
      (?<=    # 断言要匹配的文本的前缀
      <(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)
      )       # 前缀结束
      .*      # 匹配任意文本
      (?=     # 断言要匹配的文本的后缀
      <\/\1>  # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
      )       # 后缀结束

12. 贪婪与懒惰
    在匹配时你会发现如果不加以限制,正则表达式会去匹配符合当前要求的最长的字符串,例如a.*b这样的表达式,在匹配aaabab时会匹配整个字符串(aaabab),这样的匹配方式成为贪婪匹配;还有一种匹配方式,就是在符合要求的前提下尽可能短的匹配,只要给表达式合适的位置加一个?就行,这种匹配方式称为懒惰匹配。例如使用懒惰匹配去匹配aaabab时会得到aaab、ab两个子串。
                    
    参照表中的写法即可。·

13. 处理选项
    正则表达式有以下几种不同的模式。
      

14. 平衡组/递归匹配
        如何匹配<ASdfas<Asdfasdf<asdfa<adga>>>>这样多个括号嵌套的字符串?
        正则表达式提供三种语法组合使用来匹配这样的字符串。
            (?'group')    把捕获的内容命名为group,并压入堆栈
            (?'-group')    弹栈操作,弹出命名为group的捕获内容
            (?(group)yes|no)    判断堆栈,如果有group执行yes,没有匹配no
        举例说明:要匹配        <ASdfas<Asdfasdf<asdfa<adga>>>>>>>>
                使用的表达式为(((?'open'<)[^<>]*)+((?'-open'>)[^<>]*)+)*(?(open)(?!))
        注: 这个表达式最后一个组里使用的(?!)是零宽度负预测先行断言,由于后面没有表达式,所以匹配一定会失败,即当group还有,也就是匹配yes的时候就匹配失败。

15. 其他
    



写这篇我借鉴了http://www.jb51.net/tools/zhengze.html  这篇文章,在此基础上对一些问题进行了在此测试及说明。

欢迎讨论。




正则表达式全解析+常用示例

在开始写这篇文章之前,我的心里还是纠结的。我在问自己要不要写这篇东西,关于相似的内容网上多如牛毛,而且还不乏珍品,况且,就算我写了也不一定能写的好。但是现在你既然看到了,那说明我还是写了出来。就算是对...
  • xuemoyao
  • xuemoyao
  • 2012年09月29日 18:40
  • 24875

正则表达式的总结

在实际编程中经常会看到正则表达式的身影,这里我来总结总结一下正则表达式中每一部分具体都是什么含义,首先我们一个符号一个符号的学习,才能明白更为复杂的正则表达式的含义: 1.^once 可以匹配onc...

细说memcached_set

一、memcached_set 在设置好memcached_st之后,就调用memcached_set(memcached_st *ptr, const char *key, size_t key_...

正则表达式概念用法详解

  • 2011年07月12日 17:03
  • 47KB
  • 下载

正则表达式中的字符集等概念

* 字符集: 使用中括号括住字符串来创建字符集(character set),可以匹配它包括的任意字符串。 eg: ’[a-zA-Z0-9]‘ 能匹配任意大小写字母和数字。 eg: '[^abc]'可...

【简单易懂的劝退名词】正则表达式概念和入门

对计算机的学习中总会遇到一堆看不懂什么意思但是觉得很厉害的词,总会有人望而却步,所以被称为劝退名词…… 往往在高大上的名词背后其实学起来是很简单的。正则表达式就是其中之一。 下面从三个方面讲解正则表...

正则表达式中的核心概念

正则表达式的目的是操纵文本。常用的概念如下,理解了这些概念可以更方便的理解正则表达式,也可以自己来写正则表达式。 原义字符:即正常的字符,例如:A,b,c ,1,2等。 元字符:元字符代表的是一类...

正则表达式教程 概念+实战

转载请注明预见才能遇见的博客:http://my.csdn.net/ 原文地址: 正则表达式教程 概念+实战 正则表达式(regular expression)就是用一个“字符串”来描述一个特征,...
  • pcaxb
  • pcaxb
  • 2017年04月24日 18:03
  • 272

正则表达式fan反向引用相关概念总结

1       概述 捕获组捕获到的内容,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。要了解反向引用,首先要了解捕获组,关于捕获组,参考 ...

java中的正则表达式捕获组与引用的概念

今天群里有个人问,怎样用增则表达式匹配三角形的三边,其实只是要匹配三个数字而已,如 301 402 503 开始认为很简单,我就写了一个   "(([1-9]\\d?)\\s){2}$2" 结果他说错...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:正则表达式概念详解
举报原因:
原因补充:

(最多只允许输入30个字)