一、正则表达式

什么是正则表达式

  • 一套规则———匹配字符串的

能做什么

  1. 检测一个输入的字符串是否合法——web开发项目 表单验证

    • 用户输入一个内容的时候,我们要提前做检测

    • 能够提高程序的效率并且减轻服务器的压力

  2. 从一个大文件中找到所有符合规则的内容——日志分析或爬虫

    • 能够高效的从一大段文字中快速找到符合规则的内容

二、正则规则

所有的规则中的字符就可以刚好匹配到字符串中的内容

字符组 [ ] :描述的是一个位置上能出现的所有可能性

  • 接受范围,可以描述多个范围,连着写就可以了

  • [abc]:一个中括号只表示一个字符位置

    • 匹配a或b或者c

  • [0-9]:根据ASCII进行范围的比对

  • [a-z]:匹配a到z范围内的所有小写字母

  • [A-Z]:匹配A到Z范围内的所有大写字母

  • [a-zA-z]:匹配所有大小写字母

  • [0-9a-z]:匹配0到9和所有的小写字母

  • [0-9a-zA-Z_]:匹配所有数字大小写字母和下划线

在正则表达式中能够帮助我们表示匹配的内容的符号都是正则中的 元字符

  • [0-9] ———> \d:表示匹配一位任意数字(digit)

  • [0-9a-zA-Z_]———> \w:表示匹配数字字母下划线(word)

  • 空格 ———> 就是空格

  • tab ———> \t:匹配tab空白

  • enter回车 ———> \n:匹配回车

  • 空格,tab和回车———> \s:表示匹配所有空白包括空格tab和回车

元字符——匹配内容的规则

  • []:——匹配字符组内的一个字符

  • [^]:——除了字符组内的内容都匹配

  • \d:——匹配所有的数字

  • \D 和 [^\d]:——匹配所有非数字(大写D)

  • \w:——匹配所有的字母

  • \W 和 [^\w]:——匹配所有的非字母(大写W)

  • \s:——匹配所有的空白

  • \S:——匹配所有的非空白(大写S)

  • [\d\D]、[\w\W]、[\s\S]:——表示匹配所有

  • . ——匹配除了执行换行符之外的所有

  • ^:——匹配一个字符串的开始比如(^\d)匹配以数字开头的

  • $:——匹配一个字符串的结尾比如(\d$)匹配以数字结尾的

  • a表达式|b表达式:——匹配a或者b表达式中的内容,如果a匹配成功了,不会继续和b匹配,所以,如果两个规则有重叠部分,总是把长的放在前面

  • ():——分组,约束或描述的内容的范围问题

    • 匹配 www.baidu.com 或 www.oldboy.com 或 www.jd.com
      方法一:www\.oldboy\.com|www\.baidu\.com|www\.jd\.com
      方法二:www\.(oldboy|baidu|jd)\.com

三、量词

  • {n}:——表示匹配n次

  • {n,}:——表示匹配至少n次

  • {n,m}:——表示至少匹配n次,最多匹配m次

  • ?:——表示匹配 0 次或 1 次 {0,1}

  • +:——表示 1 次或多次 {1,}

  • *:——表示 0 次或多次 {0,}

匹配0次:

  • 整数:\d+

  • 小数:\d+\.\d+

  • 整数或小数:\d+\.?\d*(23423.)也会匹配上

  • 分组的作用匹配小数或整数:\d+(\.d+)?

手机号码:

  • 1 3-9 11位

    • 1[3-9]\d{9}

    • 第一位是1开头,第二位是3-9范围的任意数字后面是9位数字

判断用户输入的内容是否合法,如果用户输入的对就能查到结果,如果输入的不对就不能查到结果

  • 加上首尾匹配元字符:就会固定匹配一个满足条件的字符

    • ^1[3-9]\d{9}$

贪婪匹配:

  • 在量词允许的情况下,尽量多的匹配内容

  • .*x:表示匹配任意字符,任意多次数,遇到最后一个x才停下来

非贪婪(惰性)匹配

  • .*?x:表示匹配任意字符,任意多次数,但是一旦遇到x就停下来

  • 在量词后加?号就会变成惰性匹配

转义符

  • 原本有特殊意义的字符,到了表达它本身的意义的时候,需要转义

  • 有一些有特殊意义的内容,放在字符组中,会取消它的特殊意义

    • [().*+?]——所有的内容放在字符组中会取消它的特殊意义

    • [a\-c]:——在字符组中 - 表示范围,如果不希望它表示范围,需要转义,或者放在字符组的最前面或最后面

四、re模块

  • re.findall ('表达式','需要匹配的内容') :

    • 以字典的形式返回匹配到的所有字符串

    import re
    ret = re.findall('\d+','123abc456def')
    print(ret)
    # 输出
    ['123', '456']

     

    • findall:遇到分组的时候,会按照完整的正则进行匹配,只是显示括号里匹配到的内容

    • 取所有符合条件的,优先显示分组中的

    ret = re.findall('2(\d)\d','1234abcd4267efgh')
    print(ret)      # 只会显示匹配到234和267的第二个字符
    # 输出
    ['3', '6']

     

  • re.search('表达式','需要匹配的内容'):

    • 匹配第一个满足条件到的字符返回的是一个变量,只能用group()查看。

    ret = re.search('\d+','123abc456def')
    print(ret)  # 返回的是变量
    if ret:     # 匹配到了才显示,没匹配到返回 None,所以做了个判断
        print(ret.group())
    # 输出
    <re.Match object; span=(0, 3), match='123'>
    123

     

    • search:还是按照完整的正则进行匹配,显示也显示匹配到的第一个内容,但我们可以通过给group方法传参数来获取具体元组的内容

    • 只取第一个符合条件的,没有优先显示这件事儿

    • 得到的结果是一个变量:

      • 变量 .group() 的结果 完全和 变量 .group(0) 的结果一致

      • 变量 .group(n) 的形式来指定获取第 n 个分组中匹配到的内容

    ret = re.search('2(\d)(\d)','1234abcd4267efgh')
    print(ret)  # 变量
    if ret:
        print(ret.group())
        print(ret.group(1))
        print(ret.group(2))
    # 输出
    <re.Match object; span=(1, 4), match='234'>
    234
    3
    4

     

  • 为什么在search中不需要分组优先,而在findall中需要?

    • 在 findall中加上分组括号,是为了对真正需要的内容进行提取

    ret = re.findall('<\w+>(\w+)</\w+>','<h1>abcd12345678efgh</h1>')
    print(ret)
    # 输出
    ['abcd12345678efgh']
    在search中
    
    ret = re.search('<(\w+)>(\w+)</\w+>','<h1>abcd123678efgh</h1>')
    print(ret.group())   # 获取所有匹配到的内容
    print(ret.group(1))  # 获取第一个分组的内容
    print(ret.group(2))  # 获取第二个分组的内容
    # 输出
    <h1>abcd12345678efgh</h1>
    h1
    abcd12345678efgh

     

  • 为什么要用分组,以及 findall 的分组优先到底有什么好处

    • 使用findall分组优先可以把想要的内容放在分组里面

    • 使用search分组就可以在匹配完了之后对自己想要操作的分组进行操作

    exp = '2-3*(5+6)'
    ret = re.search('(\d+)[+](\d+)',exp)
    print(ret)          # 获取a+b或a-b,并且计算他们的结果。
    print(ret.group(1)) 
    print(ret.group(2))
    print(int(ret.group(1)) + int(ret.group(2)))

     

  • 如何取消分组优先:

    • 如果在写正则的时候由于不得已的原因,导致不要的内容也写在分组里

  • (?:)——取消这个分组的优先显示

    ret = re.findall('<(?:\w+)>(\w+)</\w+>','<h1>abcd12345678efgh</h1>')
    print(ret)
    # 输出
    ['abcd12345678efgh']

     

 

 

相关文章:

  • 2021-09-24
  • 2021-08-15
  • 2021-11-15
  • 2021-09-15
  • 2022-01-05
猜你喜欢
  • 2021-11-13
  • 2021-06-30
  • 2021-07-22
  • 2021-11-04
  • 2021-11-22
  • 2022-02-22
相关资源
相似解决方案