正则表达式

  1. 元字符
    1. \b 只是匹配开头或结尾的一个位置,而不是代表空格,点,换行符等;
      1. 示例:如果要匹配 hi 后面不远处是否有跟着一个单词 Lucy,则可以考虑这么写:\bhi\b.*\bLucy\b
    2. 点“.”可以用来匹配除了换行符以外的任何字符;星号“”代表的是数量,表示星号前面的内容可以连续重复任意次,所以二者合起来的“.*" 表示任意数量的不包含换行的字符;“+” 表示重量1次或更多次,星号可以匹配0次,但加号不行,“\d+” 表示匹配一个或者多个数字;如果要表示"." 本身,则需要使用 .
    3. \d 匹配一位数字,0,或1,或2,或3
      1. 示例1:0\d\d\d-\d\d\d\d\d\d\d,表示匹配 0 开头的,接下来3位数字,接着使用横杠连接着,后面接着7位数字的字符串,显然,可以用来表示座机号码,例如 0755-3819783
      2. 示例2:示例1的简化版,0\d{3}-\d{7}
    4. \w 匹配字母或数字或下划线或汉字
    5. \s 匹配任意的空白符,包括空格,制表符tab,换行符,中文全角空格等;
    6. ^ 匹配字符串的开始;$ 匹配字符串的结束;
      1. 示例1
        1. 问题:网站要验证输入的 QQ 号是5-12位的
        2. 答案:^\d{5,12}$
      2. 其他:
        1. 有些正则表达式的处理工具还有一个处理多行的情况,如果选中了这个选项,则 ^ 和 $ 的含义变成了匹配行的开始处和结束处;
  2. 字符转义
    1. 因为一些元字符代表了某种特别的含义,但当你想查找它们本身的话,就需要一个特殊的字符斜杠 "" 来取消它们代表的特殊含义;
  3. 重复
    1. ? 表示重复一次或零次;
    2. {n,} 重复 n 次或者更多次
    3. {n,m} 重复 n 到 m 次;
  4. 字符类
    1. 方括号可以用来表示整体的字符集
      1. 示例1:[aeiou] 表示匹配方括号中5个元音字母的任意一个
      2. 示例2:[.?!] 表示匹配方括号中点号、问号、感叹号等3个符号的任意一个
      3. 示例3:[0-9] 表示匹配 0 到 9 的任意一个数字,与 \d 是相同的意思;同理,[0-9a-zA-Z] 则等同于 \w (如果只考虑英文,不考虑汉字或下划线的话)
      4. 示例4:(?0/d{2}[) -]?\d{8},转义一个左括号,出现1次或不出现,接着2个数字,接着右括号、空格、中横杠 3 个中的 1 个或者不出现,接着 8 个数字;
  5. 分枝条件
    1. 使用竖线来代表分枝条件,注意顺序很重要,即会先判断左边的分枝是否满足,如果满足,则不再检查右边的分枝;如果不满足,则再检查右边的分枝是否满足;
  6. 分组
    1. 通过使用括号来对多个字符归成一组,然后可以对整组字符做操作,例如设定重复次数;
    2. 括号内的分组,也可以视同一个子表达式;
    3. 正则表达式中不能使用数学计算;
  7. 反义
    1. \W,匹配任意不是字母、数字、汉字、下划线的字符;
    2. \S,匹配任意不是空白的字符;
    3. \D,匹配任意不是数字的字符;
    4. \B,匹配任意不是开头或结尾的字符;
    5. [^x],匹配不是 x 的字符;
    6. [^aeiou],匹配不是 aeiou 这5个字符的任意字符;
    7. 示例
      1. \S+,匹配不包含空白字符的字符串;
      2. <a[^>]+>,匹配不包含右尖括号的,以 <a 开头,以 > 结尾的字符串;
  8. 后向引用
    1. 每个分组会有一个组号,从左往右,组号从1开始编号,第一组的组号为1,第二组的组号为2,以此类推;分组 0 则对应整个正则表达式;
    2. 组号分析的工作原理,是要扫描两遍的:
      1. 第1遍:扫描找出所有未命名的组,给它们依次编号;
      2. 第2遍:扫描找出所有已命名的组,给它们依次编号(接着第1遍的编号往下)
    3. 因此,所有已命名组的组号都是大于未命名的组的;
    4. 给分组命名的两种办法:
      1. 办法1:(?<组名>表达式)
      2. 办法2:(?'组名’表达式)
    5. 通过引用分组号或者分组名,可以重复引用分组捕获的内容
      1. 示例:\b(\w+)\b\s+\1\b,此处的\1表示重复前面的分组(\w+)捕获的内容;
      2. 重复引用的好处是可以让表达式写得更加简洁和易于维护;
    6. 当分组有自定义的名称时,引用的办法是:\k<组名>
  9. 常用分组语法:
    1. 捕获
      1. (exp),匹配 exp,并捕获文本到自动命名的组里;
      2. (?exp),匹配 exp,并捕获文本到命名为 name 组里;
      3. (?:exp),匹配 exp,但不捕获文本到自动命名的组里,也不给此分组分配组号;
    2. 零宽断言(#好高深的名称,什么鬼?)
      1. (?=exp),匹配 exp 前面的位置;
      2. (?<=exp),匹配 exp 后面的位置;
      3. (?!exp),匹配后面跟的不是 exp 的位置;
      4. (?<exp),匹配前面跟的不是 exp 的位置;
    3. 注释
      1. (?#注释内容),表示一个注释,仅阅读,不产生任何作用或副作用;
  10. 零宽断言
    1. (?=exp),零宽度正预测先行断言,它断言自身出现位置的后面,能匹配表达式 exp
      1. 示例:\b\w+(?=ing\b),匹配以 ing 结尾的单词的前面部分
        1. I’m singing while you’re dancing
        2. 匹配 sing 和 danc
    2. (?<=exp),零宽度正回顾后发断言,它断言自身出位位置的前面,能匹配表达式 exp
      1. 示例:(?<=\bre)\w+\b,匹配以 re 开头的单词的后面部分;
        1. reading a book
        2. 匹配 ading
    3. 其他
      1. 断言用来声明一个应该为真的事实,正则表达式中只有断言的结果为真时,才会继续进行匹配;如果断言不为真,则匹配终止;
      2. (?<=\s)\d+(?=\s),匹配以空白字符间隔的数字;
  11. 负向零宽断言(这个翻译真垃圾,或许应该叫:匹配不包含表达式指定的内容)
    1. (?!exp),断言此位置的后面不能匹配表达式 exp
      1. 示例:\d{3}(?!\d),匹配3个数字,且后面不能再跟着数字;
      2. 示例:\b((?!abc)\w)+\b,不包含连续字符串 abc 的单词;
      3. 与[^exp] 的区别:[^exp] 会消费一个字符进行判断,而 (?!exp) 不会
    2. (?<!exp),断言此位置的前面不能匹配表达式 exp
      1. 示例:(?<![a-z])\d{7},匹配不以小写字母开头的7位数字;
      2. 示例:(?<=<(\w+)>).*(?=<//1>),匹配不包含属性的简单 html 里面的内容;
    3. 不管是零宽断言,还是负向零宽断言,它都表示所断言的是其位置前后的情况,其本身不包含前后的内容;
  12. 注释
    1. 语法:(?#注释内容)
      1. 示例:2[0-4]/d(?#200-249)|250-5|[01]?\d\d?(?#0-199)
    2. 建议启用选项"忽略模式里面的空白符,好处是:可以在注释中,随意添加空白符,例如空格、换行、TAB等,这些空白符都会被忽略不执行;
      1. 示例
        1. (?<= # 断言要匹配的文本的前缀)
        2. <(\w+)> # 查看尖括号括起来的字母或数字,即 html/xml 标签;
        3. ) # 前缀结束
        4. .* # 匹配任意文本
        5. (?= # 断言要匹配的文本的后缀)
        6. <//1> # 查找尖括号括起来的内容,其中前面一个字符是"/",后面是先前分组捕获的内容
        7. ) # 后缀结束
  13. 贪婪与懒惰
    1. 正常情况默认是贪婪匹配,即能够满足条件下匹配尽可能多的字符;
    2. 懒惰匹配则是能满足条件下匹配尽可能少的字符;
    3. 示例
      1. a.*b,匹配以 a 开头,以 b 结尾的字符串,例如匹配 aabab,会得到整个字符串
      2. a.*?b,匹配以 a 开头, 以 b 结尾的字符串,但使用最少的重复,例如匹配 aabab,会得到 aab 和 ab 两个字符串
    4. 懒惰限定符
      1. *?,重复任意次,但尽可能少重复
      2. +?,重复1次或任意次,但尽可能少重复;
      3. ??,重复0次或1次,但尽可能少重复
      4. {n,m}?,重复 n-m 次,但尽可能少重复;
      5. {n,}?,重复 n 次以上,但尽可能少重复;
  14. 平衡组/递归匹配
    1. 思路:
      1. 从最左边开始,每找到一个左括号,将捕获的内容命名为 group,压入栈,直到将所有左括号找完;
      2. 每找到一个右括号,从栈中弹出一个组 group
      3. 如果堆栈上存在 group 的捕获内容,则执行匹配 yes 的表达式;如果不存在 group,则执行匹配 no 的表达式;
    2. 平衡组常用的一个应用是匹配 html 标签,例如嵌套的
      标签
    3. 不同的语言/库可能不一定支持此功能,或者支持此功能但使用的语法可不同
  15. python 中 re 模块的一些处理函数
    1. re.match
      1. 作用:匹配字符,如果成功则返回 Match,如果失败则返回 None
      2. 示例:
        1. text = ‘John is a handsome boy, he is clever, cool, and so on.’
        2. m = re.match(r"(\w+)\s", text)
      3. 释义
        1. 函数原型:re.match(pattern, string, flags)
        2. 第一个函数是要匹配的内容,第二个是字符串,第三个控制参数,例如区分大小写、多行匹配等
    2. re.search
    3. re.sub
    4. re.split
    5. re.findall
    6. re.compile

正则表达式
https://ccw1078.github.io/2017/04/04/正则表达式/
作者
ccw
发布于
2017年4月4日
许可协议