正则表达式学习


关于正则表达式的学习笔记和总结

浅谈正则表达式

我有一个问题可以用正则表达式解决,好了现在我有两个问题了
为什么是正则表达式

在我个人的学习经历中接触过各种字符串查找函数,但为什么正则表达式这么神奇?我觉得是它的模糊性,它的模糊性决定了查找时无关元素的影响更小,更能找到需要的内容

用一段python代码举例

str = "abcdef"
res = str.find("a")

这个代码能帮助你找到字符串中a这个字符,但如果换个问题,在一堆电话号码中找某一个开头的电话,或者末尾是某一片段的电话号码,那么,find函数就没这么好用了。
这时候,正则表达式的模糊性就能很好的得到需要的结果。

正则表达式的应用范围

正则表达式在java和python等语言中都有相应的包调用.在爬虫的使用中,正则表达式能很好的从一堆标签中找到你需要的某一段消息(虽然有时候在结构规整,目标不复杂的情况下,bs4有更好的效果).

正则表达式规则

元字符

  1. . :匹配除换行符之外的任意字符
  2. \w :匹配字母或数字或下划线或汉字
  3. \W :匹配不是字母或数字或下划线或汉字的字符
  4. \s :匹配任意空白符
  5. \S :匹配任意非空白符
  6. \d :匹配数字
  7. \D :匹配非数字
  8. \b :匹配单词的开始或结束 如"er\b" 可以匹配never 不能匹配 very
  9. \A :匹配字符串开头
  10. \z:匹配字符串结尾,如果有换行符,则同时匹配换行符.
  11. \Z:匹配字符串结尾,不匹配换行符.
  12. ^ :匹配输入字符串的开始
  13. $ :匹配输入字符串的结束

    重复限定符

  14. * 重复零次或者多次
  15. + 重复一次或多次
  16. ?重复零次或一次
  17. {n} 重复n次
  18. {n,} 重复n次或者多次
  19. {n,m} 重复n次或者m次

    分组符

  20. (ab) 表明以字符串"ab"为一组的元素,例如: "^(ab)+"匹配以零个或者多个"ab"开头的字符串
  21. [abc]或者[a-c] 表明匹配abc中任意一个的字符

    转义符

  22. \ 表明将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。如:"(\n)"表示匹配\n "(\(ab\))+"表示匹配一个或者多个"(ab)"的字符

    条件符

  23. | 条件或,满足前者或者后者的字符,例如"(12)(3|4)"匹配"123"或者"124"的字符

    断言

  24. 正向先行断言表达式1(?=pattern)匹配pattern前面的表达式,不包含本身,例如下面的代码
    import re
    line = "<div class = \"left_box\" height = 100px>"
    pattern = ".*(?=height)"
    m = re.search(pattern,line)
    print(m.group(0))
    >>> <div class = "left_box" 
  25. 负向先行断言表达式1(?!pattern)匹配后面不含pattern的表达式,不包含本身,例如下面的代码
    import re
    line = "regular regex rlief"
    pattern = r"r(\w{1})(?!g)"
    m = re.search(pattern,line)
    print(m.group(0))
    >>> rl
  26. 正向后行断言(?<=pattern)表达式1,同正向先行断言,只是匹配的是pattern后面的表达式
  27. 负向向后行断言(?<!pattern)表达式1,同负向向先行断言,只是匹配的是pattern后面的表达式

懒惰(非贪婪)

什么是正则表达式的贪婪?

贪婪是指在匹配时尽可能多的匹配,如\w{2,9}则会尽量匹配9个,如果不够就匹配八个.

如何做到懒惰
  1. *?重复0次或者无数次,从0开始匹配
  2. +?重复一到正无穷次,从1开始
  3. ??重复0到1次,从0开始
  4. {n,m}? 重复n到m次,从n开始

    编号分组

  5. 数字编号分组{表达式},例如:
    import re
    line = "020-85653333"
    pattern = r"(0\d{2,3})-(\d{8})"
    m = re.search(pattern,line)
    m.group(0)
    >>>020-85653333
    m.group(1)
    >>>020
    m.group(2)
    >>>85653333
  6. 命名编号捕获组(?<name>表达式),非捕获组()?:表达式,不捕获(在不同语言中实现方式不同,如在python中需要添加P在?与之间)
    import re
    line = "020-85653333"
    pattern = r"(?P<区号>0\d{2,3})-(?P<号码>\d{8})"
    m = re.search(pattern,line)
    m.group(0)
    >>>020-85653333
    m.group("号码")
    >>>020
    m.group("区号")
    >>>85653333
    
    import re
    line = "020-85653333"
    pattern = r"(?P<区号>0\d{2,3})-(?:\d{8})"
    m = re.search(pattern,line)
    m.group(0)
    >>>020-85653333
    m.group("号码")
    >>>Error
    m.group("区号")
    >>>85653333

    python中re库介绍

    修饰符

  • re.I 大小写不敏感
  • re.L 实现本地化识别(local-aware)匹配
  • re.M 多行匹配
  • re.S 匹配包括换行符在内的任何字符
  • re.U 使用Unicode字符集解析字符
  • re.X 该标志给予灵活格式.

方法

  • search:从开头开始匹配,如果开头不匹配则失败
  • findall:获取匹配的所有字符串
  • sub:把匹配字符出从其中删去
  • compile:将正则表达式编译成正则表达式对象,方便之后复用
  • match:找到第一个匹配的字符串

参考网站

正则表达式在线匹配网站:https://c.runoob.com/front-end/854/


Author: Dovahkiin
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Dovahkiin !
  TOC