python基础语法 - 正则表达式

正则表达式

  • 正则表达式字符串
    • 元字符
    • 转义字符
    • 开始与结束符
  • 字符类
    • 定义字符类
    • 字符类取反
    • 区间
    • 预定义字符类
  • 量词
    • 量词的使用
    • 贪婪和懒惰
  • 分组
    • 分组的使用
    • 分组命名
    • 反向引用分组
    • 非捕获分组
  • re模块
    • search()和match()函数
    • findall()和finditer()函数
    • 字符串分割
    • 字符串替换

  • 是什么:Regular Expression,简写RE,是预先定义好的一个“规则字符串”,通过这个规则字符串可以匹配、查找和替换那些符合规则的文本。
  • 优点:文本的查找替换虽然可以使用字符串提供的方法实现,但是实现较为困难,运算效率低。使用正则效率高。
  • 缺点:编写合适的正则表达式较为困难。
  • python中应用:数据挖掘、数据分析、网络爬虫、输入有效性验证等待。

正则表达式字符串

  • 正则表达式是一种字符串,它由普通字符和元字符组成的。
  • 普通字符:按照字符字面意义的字符。
  • 元字符:预先定义好的一些特定字符。
  • 如验证邮箱的正则表达式:\w+@zhengzetang\.com,其中\w+\.属于元字符;@zhengzetangcom是普通字符。

元字符

  • 用来描述其他字符的特殊字符,由基本元字符和普通字符构成,基本元字符是构成元字符的组成要素。基本元字符有14个,如下表python基础语法 - 正则表达式_第1张图片

转义字符

  • 以上面匹配邮箱的字符串\w+@zhengzetang\.com为例
  • w字符不表示英文字母w,而是表示任何语言的单词字符、数字或下划线等内容时,需要在w前面加上反斜杠“\”。
  • .本身是基本元字符,代表任意一个字符,但是我们希望按照.字面的意义使用(就是一个点),这时候加上一个反斜杠“\”就可以实现了。
  • 转义字符\就是对普通字符或基本元字符,进行转义,用于其他功能。

开始与结束符

  • 前面提到了^$,用以匹配一行字符串的开始和结束。
  • 当以^开始时,要求一行字符串的开始位置匹配。
  • 当以$结束时,要求一行字符串的结束位置匹配。
    import re 
    
    p1 = r'\w+@tianshangrenjian\.com'
    p2 = r'^\w+@tianshangrenjian\.com$'
    
    text = "My email is [email protected]."
    m = re.search(p1, text)
    print(m)
    
    # 匹配不到,有^,$符号,匹配时要求text字符串开始和结束都要与正则表达式开始和结束匹配。
    a = re.search(p2,text)
    print(a)
    
    # email字符串的开始与结束与正则表达式相匹配
    email = '[email protected]'
    b = re.search(p2, email)
    print(b)
    
  • 显示结果
    在这里插入图片描述

字符类

  • 正则表达式种可以使用字符类(character class),一个字符类定义一组字符,其中的任一字符出现在输入字符串中即匹配成功。
  • 注意:每次匹配只能匹配字符串中的一个字符。

定义字符类

  • 定义一个普通的字符类,使用[]元字符类。例,想在字符串中匹配java或Java,可以使用正则表达式[Jj]ava
    import re
    
    p = r'[Jj]ava'
    
    # 可以匹配
    m = re.search(p, 'i like Java and Python')
    print(m)
    
    # 可以匹配
    c = re.search(p, 'i like java and Python')
    print(c)
    
    # 不可匹配
    b = re.search(p, 'i like JAVA and Python')
    print(b)
    
    # 想要匹配JAVA,可以使用|
    p2 = r'java|JAVA|Java'
    d = re.search(p2, 'i like JAVA and Python')
    print(d)
    
  • 运行结果为
    在这里插入图片描述

字符类取反

  • 在正则表达式中指定不想出现的字符, 可以在字符前加^符号。
    import re 
    
    p = r'[^0123456789]'
    
    # 不匹配数字
    m = re.search(p, '239120392')
    print(m)
    
    # 除了非数字外,都可以匹配任意字符
    a = re.search(p, 'Reasdskf')
    print(a)
    
  • 运行结果
    在这里插入图片描述

区间

  • 如果要表示连续的数字,用[^0123456789],较为复杂,可以使用区间符号-表示。即[^0123456789]等同于[^0-9]
  • 连续的英文字母可以表示为[a-z],大写[A-Z]
  • 可以表示多个不同区间,如[A-Za-z0-9]表示所有字母和数字字符类,[0-25-7]表示0,1,2,5,6,7
    import re 
    
    p = r'[a-zA-Z0-9]'
    
    # 匹配
    m = re.search(p, 'A10.3')
    print(m)
    
    # 不匹配
    a = re.search(r'[0-25-7]', 'A3489C')
    print(a)
    

预定义字符类

  • 有些字符很常用,如[0-9]等,为了书写方便,正则表达式提供了预定义的字符类。
    python基础语法 - 正则表达式_第2张图片
  • 示例
    import re
    
    # p = r'[^0123456789]'
    p = r'\D'
    
    # 不匹配
    m = re.search(p, '11003')
    print(m)
    
    # 匹配
    a = re.search(p, 'ajdka')
    print(a)
    
    text = "hello world。"
    b = re.search(p, text)
    print(b)
    
  • 运行结果
    在这里插入图片描述

量词

  • 上面说的正则,只能匹配显示一次字符或字符串,如果想匹配显示多次字符或字符串可以使用量词。

量词的使用

  • 量词表示字符或字符串重复的次数,量词如下表
字符 说明
? 出现零次或一次
* 出现零次或多次
+ 出现一次或多次
{n} 出现n次
{n, m} 至少出现n次但不超过m次
{n, } 至少出现n次
  • 示例
    import re
    
    m = re.search(r'\d?', '87654321')   # 出现数字一次,匹配字符8
    print(m)
    
    a = re.search(r'\d?', 'adxcx')      # 出现数字0次,匹配''
    print(a)
    
    b = re.search(r'\d*', '2134354afas123') # 出现数字多次,匹配2134354
    print(b)
    
    c = re.search(r'\d{8}', '87654321')     # 出现数字8次,匹配87654321
    print(c)
    
    d = re.search(r'\d{9,}', '87654321')    # 出现数字8次,但要求9次,不匹配
    print(d)
    
  • 运行结果
    在这里插入图片描述

贪婪和懒惰

  • 量词细分为贪婪量词和懒惰量词。
  • 贪婪量词会尽可能多地匹配字符,懒惰量词会尽可能少地匹配字符。
  • 大多数计算机语言的正则表达式词默认是贪婪的,要想使用懒惰量词在量词后面加 ?
    import re
    
    # 使用贪婪量词
    m = re.search(r'\d{5,8}', '87456123')   # 至少出现5次,不少于8次,贪婪匹配8次
    print(m)
    
    # 使用懒惰量词
    a = re.search(r'\d{5,8}?', '87456123')  # 懒惰匹配5次
    print(a)
    
  • 运行结果
    在这里插入图片描述

分组

  • 分组也称为子表达式,就是将一个字符串放到一对小括号中,让一个字符串作为整体使用量词。

分组的使用

  • 对正则分组不仅可以对一个字符串整体使用量词,也可以在正则中引用已存在的分组。

  • 示例

    import re
    
    p = r'(121){2}'
    m = re.search(p, '121121121adfd')   # 匹配121121
    print(m)
    print(m.group())    # 返回匹配的字符串
    print(m.group(1))   # 返回第一组内容
    
    a = r'(\d{3,4})-(\d{7,8})'
    b = re.search(a, '010-7785457322a')
    print(b)
    print(b.group())
    print(b.group(1))
    
  • 运行结果
    python基础语法 - 正则表达式_第3张图片

分组命名

  • 组命名:在组开头添加?P<分组名>
  • 分组命名后,方便程序访问分组。
  • 示例
    import re
    
    p = r'(?P\d{3,4})-(?P\d{7,8})'
    
    b = re.search(p, '010-77548573')
    print(b)
    print(b.group())
    print(b.groups())
    
    # 通过组编号返回
    print(b.group(1))
    print(b.group(2))
    
    # 通过组名返回
    print(b.group('area_code'))
    print(b.group('phone_code'))
    
  • 运行结果
    python基础语法 - 正则表达式_第4张图片

反向引用分组

非捕获分组

  • 捕获分组:匹配子表达式的结果被暂时保存到内存中,以备表达式或其他程序使用,这个过程就是“捕获”,捕获结果可以通过组编号或组名进行引用。
  • 非捕获分组:与上面相反,不想存,不想引用,只是单纯的匹配。
  • 实现方法:组开头使用?:
    import re
    
    s = 'img1.png, img2.png, img3.jpg, img4.png'
    
    # 捕获分组,将括号中的内容作为子表达式进行捕获匹配,将组的内容返回
    p1 = r'\w+(\.png)'
    mlist = re.findall(p1,s)
    print(mlist)
    
    # 非捕获分组,将括号中的内容作为普通正则字符串进行整体匹配,即找到.png结尾的文本
    p2 = r'\w+(?:\.png)'
    nlist = re.findall(p2,s)
    print(nlist)
    
  • 运行结果
    在这里插入图片描述

re模块

  • re模块是python内置的正则表达式模块。

search()和match()函数

  • 两者非常相似, 区别如下:
    • search():在输入字符串中查找,返回第一个匹配内容,找到就匹配对象,没找到就返回None
    • match():在输入字符串开始处查找匹配内容,找到就匹配对象,没找到就返回None
  • 示例
    import re
    
    p = r'\w+@woaipython\.com'
    
    text = 'my email is [email protected]'
    # 能匹配
    m = re.search(p,text)
    print(m)
    
    # 不能匹配
    n = re.match(p,text)
    print(n)
    
    email = '[email protected]'
    # 能匹配
    a = re.search(p,email)
    print(a)
    
    # 能匹配
    b = re.match(p, email)
    print(b) 
    
  • 运行结果
    在这里插入图片描述
  • match对象的几个方法:
    email = '[email protected]'
    b = re.match(p, email)
    print(b)
    print(b.group())
    print(b.start())
    print(b.span())
    print(b.end())
    
  • 运行结果
    在这里插入图片描述

findall()和finditer()函数

  • 两者相似,区别如下:
    • findall():在输入字符串中查找所有匹配内容,如果匹配成功,返回match列表对象,否则返回None。
    • finditer():在输入字符串中查找所有匹配内容,如果匹配成功,返回容纳match的可迭代对象,通过迭代对象每次可以返回一个match对象,如果失败则返回None。
    import re
    
    p = r'[Pp]ython'
    text = 'i like python or Python.'
    
    match_list = re.findall(p, text)
    print(match_list)
    
    match_iter = re.finditer(p, text)
    for i in match_iter:
        print(i)
        print(i.group())
    
  • 运行结果
    python基础语法 - 正则表达式_第6张图片

字符串分割

  • 函数split(),按照匹配的子字符串进行分割,返回字符串列表对象。
  • 构造方式:re.split(pattern, string, maxsplit=0, flags=0)
  • pattern:正则表达式
  • string:要分割的字符串
  • maxsplit:最大分割次数,默认为0,意味着分割次数没有限制
  • flags:编译标志。
    import re
    p = r'\d+'
    text = 'ABCD12EF33gh'
    
    clist = re.split(p, text)
    print(clist)
    
    dlist = re.split(p, text, maxsplit=1)
    print(dlist)
    
    elist = re.split(p, text, maxsplit=2)
    print(elist)
    
  • 运行结果
    在这里插入图片描述

字符串替换

  • 函数sub(),用于替换匹配的字符串,返回值是替换之后的字符串。
  • 构造方式:re.sub(pattern, repl, string, count=0, flags=0)
  • pattern:正则表达式
  • repl:要替换字符串
  • string:要提供的字符串
  • count:要替换的最大数量,默认为0,意味着替换没有次数
  • flags:编译标志
    import re 
    p = r'\d+'
    text = 'ABCD12EF33gh'
    
    replace_text = re.sub(p, ' ', text)
    print(replace_text)
    replace_text = re.sub(p, ' ', text, count=1)
    print(replace_text)
    replace_text = re.sub(p, ' ', text, count=2)
    print(replace_text)
    
  • 运行结果
    在这里插入图片描述

你可能感兴趣的:(Python学习笔记,正则表达式,python,开发语言)