首页 > 代码库 > 正则表达式五分钟快速复习

正则表达式五分钟快速复习

项目小版本上线偷得半日闲,刚刚又重新看了一遍正则,这次有空仔细看,完全理解了一遍,收获很大,下面整理一下

  1. 总体
    1. 正则其实非常简单,没有太多东西,就只有几个组成部分:表示字符/表示数量/表示位置/其他
    2. 不过确实正则可读性非常差,我觉得首要原因就是组成成分混乱,所以我的技巧是分两步,第一步是断句,第二步是理解,断句非常重要
  2. 表示字符
    1. 普通字符
      1. 任意字符(元字符需要转义)(空格也是直接匹配)
    2. 元字符(匹配一类字符)
      1. . -匹配除换行符以外的任意字符
      2. \w -匹配字母或数字或下划线或汉字(word)
      3. \s -匹配任意的空白符(skip)
      4. \d -匹配数字(digit)
    3. 表达式
      1. [-]反括号能匹配里边的元素,能通过-表示一个范围
      2. 举例
        1. [aeiou]就匹配任何一个英文元音字母
        2. [.?!]匹配标点符号(.或?或!)
        3. [0-9]代表的含意与\d就是完全一致的:一位数字
        4. [a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)
  3. 表示数量(限定符)
    1. 元字符
      1. * -重复零次或更多次
      2. + -重复一次或更多次
      3. ? -重复零次或一次
    2. 表达式
      1. {n} -重复n次
      2. {n,} -重复n次或更多次
      3. {n,m} -重复n到m次
    3. 贪婪/懒惰
      1. 看着高大上但是很简单的概念,用起来也非常简单,就一个字符
      2. 在限定符后边加一个?就意味着从贪婪匹配变成了懒惰匹配
      3. 当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符
        1. 以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串
        2. 如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配
      4. 有时我们更需要懒惰匹配,也就是匹配尽可能少的字符
        1. 比如 .*? 就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
  4. 表示位置
    1. 都是元字符,没几个
    2. \b -匹配单词的开头或结尾,它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)\w  (begin)
    3. ^ -匹配字符串的开始
    4. $ -匹配字符串的结束
  5. 零宽断言
    1. 它跟表示位置有点类似的地方,有人直接认为它就是表示位置的一种方法,但我不这么认为,我认为它不一样的原因是它可以截取字符串
    2. 它本身还有一个特殊属性是,它不会占有匹配位,也就是它不会匹配掉字符,而前面的匹配字符和匹配位置都是会匹配掉字符的(结合表示位置的元字符理解更佳)
    3. 表达式
      1. (?=exp) -匹配exp前面的位置
        1. 断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分)
      2. (?<=exp) -匹配exp后面的位置
        1. 断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分)
      3. (?!exp) -匹配后面跟的不是exp的位置
        1. 断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字
      4. (?<!exp) -匹配前面不是exp的位置
        1. 断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字
  6. 其他
    1. 元字符和转义字符
      1. 这块我觉得正则做得不太好,<有意义,但是却不是转义字符,只能通过前后文判断它属于什么情况下,还有空格的表示,虽然不会有语法错误,但都降低了表达式的可读性
      2. 转义字符是反斜杠,它其实有二元的作用,普通字符加反斜杠会成元字符,本身就是元字符的特殊字符加反斜杠表示它本身(表示为普通字符身份)
      3. 这里提三个关于字符的概念:元字符/普通字符/特殊字符
        1. 所有字符分为普通字符(所有大小写英文字母)、特殊字符(符号类的)、数字 和 其他字符(中文/日文什么鬼的根本不管的字符)
        2. 而元字符是从普通字符和特殊字符中挑选出来的字符,特殊字符成为元字符形式上不会有变化,普通字符成为元字符形式上需要加一个反斜杠
      4. 所有元字符统计
        1. (、)、|、. 、*、+、?、^、$、\、{、}、/、
        2. 不是元字符的统计
          1. 短横线、减号、<、>、
    2. 反义字符
      1. 这是一整套东西,一整套简单的东西,而且在命令上有规律
      2. 用它的目的是想查找除了数字以外,其它任意字符都行的情况
      3. 默认命令的话就是小写改大写,非默认命令是加^,如下
        1. \W -匹配任意不是字母,数字,下划线,汉字的字符
        2. \S -匹配任意不是空白符的字符
        3. \D -匹配任意非数字的字符
        4. \B -匹配不是单词开头或结束的位置
        5. [^x] -匹配除了x以外的任意字符
        6. [^aeiou] -匹配除了aeiou这几个字母以外的任意字符
    3. 分组
      1. 正则里是使用小括号进行分组的,这里的分组有两个作用
        1. 第一个跟其他地方使用小括号分组是一样的,都是表示运算的优先级,可以把括号内的内容当成一个优先级更高的整体
        2. 第二个是 后向引用
          1. 默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2
          2. 而后边的表达式中可以通过组号引用前面的组内容,比如\1 代表分组1匹配的文本
          3. 也可以自己指定子表达式的组名:(?<Word>\w+)(或者把尖括号换成‘也行:(?‘Word‘\w+)),这样就把\w+的组名指定为Word了,引用这个分组捕获的内容:\k<Word>
          4. 另外(?:exp)匹配exp,不捕获匹配的文本,只是为了不给此分组分配组号
    4. 分支条件
      1. 正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配
      2. 具体方法是用|把不同的规则分隔开
      3. 分支符号运算顺序最低,但是可以使用小括号来灵活调整范围
    5. 注释
      1. 通过语法(?#comment)来包含注释

参考文献:

http://deerchao.net/tutorials/regex/regex.htm

正则表达式五分钟快速复习