10 正则表达式

    技术2022-07-10  162

    10 正则表达式

    re 模块:Python提供的专门使用正则表达式的相关的函数的模块

    10.1 了解正则表达式

    什么是正则表达式?

    正则表达式是一种让字符串处理简单的工具(本质是做字符串匹配)

    正则表达式的语法 fullmatch(正则表达式,字符串) - 让正则表达式和字符串进行完全匹配,如果匹配失败结果是None js的正则: /正则表达式/ python的正则: r'正则表达式'

    10.2 匹配符号

    普通字符 - 表示字符本身 re_str = r'abc' result = fullmatch(re_str, 'abc') print(result) . - 匹配一个任意字符 re_str = r'.abc' result = fullmatch(re_str, '+abc') print(result)

    练习:匹配一个长度是5的字符串,字符串中间三个字符是abc,第一个字符和最后一个字符任意

    re_str = r'.abc.' result = fullmatch(re_str, '(abc+') print(result)

    练习:匹配一个长度是3的任意字符串

    re_str = r'...' result = fullmatch(re_str, 'ajs') print(result) \w - 匹配任意一个数字、字母或者下划线(针对ASCII码表有效)(注意:平时不用) re_str = r'\wabc' result = fullmatch(re_str, '8abc') print(result) \d - 匹配任意一个数字字符 re_str = r'\d\d\d' result = fullmatch(re_str, '142') print(result) re_str = r'\d\dabc\d\d' result = fullmatch(re_str, '23abc89') print(result) \s - 匹配任意一个空白字符 re_str = r'\s\d..' result = fullmatch(re_str, '\n9k/') print(result) re_str = r'\d\d\s\d\d' result = fullmatch(re_str, '78 23') print(result) \D和\S """ \字母 - 小写字母和对应的大写字母的功能相反 """ re_str = r'\dabc\D' result = fullmatch(re_str, '8abc-') print(result) re_str = r'\Sabc' result = fullmatch(re_str, '=abc') print(result) [字符集] - 匹配字符集中出现的任意一个字符 """ 注意:一个[]只能匹配一个字符 a. [abc123] - 匹配 a、b、c、1、2、3 中任意一个字符 b. [a-z] - 匹配从字符a到字符z之间的任意一个字符(匹配任意一个小写字母) [A-Z] - 匹配任意一个大写字母 [a-zA-Z] - 匹配任意一个字母 [0-9] - 匹配任意一个数字字符 [\u4e00-\u9fa5] - 匹配任意一个中文字符 """ re_str = r'[cz+?]123' result = fullmatch(re_str, '?123') print(result) re_str = r'[\u4e00-\u9fa5]123' result = fullmatch(re_str, '看123') print(result)

    练习:判断输入手机号码是否合法

    re_str = r'1[3-9]\d\d\d\d\d\d\d\d\d' result = fullmatch(re_str, '13598902763') print(result) # []中-前面的字符编码值必须小于-后面的字符编码 # result = fullmatch(r'[a-0]abc', '0abc') # []中-如果不在两个字符之间,-就没有特殊功能直接表达它本身 result = fullmatch(r'[-09]abc', '-abc') print(result)

    练习:写一个正则表达式,要求可以匹配一个字符串:abc前面是一个数字、字母或者下划线

    re_str = r'[a-zA-Z\d_]abc' result = fullmatch(re_str, '_abc') print(result)

    8)[^字符集] - 取不在字符集中任意一个字符

    """ [^\u4e00-\u9fa5] - 匹配任意一个非中文字符 [^0-9] - 匹配任意一个非数字字符 [^a-zA-Z] - 匹配任意一个非字母字符 """ print(fullmatch(r'[abc^]123', 'b123')) print(fullmatch(r'[^abc]123', 'a123'))

    10.3 检测符号

    1)\b - 检测是否是单词的边界

    """ 单词边界:字符串开头、字符串结尾、凡是能区分出两个不同单词的符号 注意:检测类的符号不影响匹配的长度,只是在匹配成功的时候做进一步的检测 """ message = 'how are you?i am fine!thank you!' re_str = r'\d\d.\b\d\d' print(fullmatch(re_str, '56=89'))

    2)^ - 检测^所在的位置是否是字符串开头

    re_str = r'\d^abc' print(fullmatch(re_str, '1abc')) re_str = r'^\d\d\d' print(fullmatch(re_str, '678')) re_str = r'^\d\d\d' print(fullmatch(re_str, '678')) print(search(re_str, 'shdj39极客时间238u丄282='))

    3)$ - 检测$所在的位置是否是字符串结尾

    re_str = r'\d\d$' print(search(re_str, '时代峰峻78暗示法23沙发89'))

    10.4 匹配次数

    1)* - 匹配0次或多次

    """ 字符* - 字符出现0次或多次 """ re_str = r'a*' print(fullmatch(re_str, 'aaa')) re_str = r'\d*' print(fullmatch(re_str, '478923')) re_str = r'123[a-z]*' print(fullmatch(re_str, '123ukl'))

    2)+ - 匹配1次或多次(至少1次)

    re_str = r'a+' print(fullmatch(re_str, 'a')) ? - 匹配0次或1次 re_str = r'\d?abc' print(fullmatch(re_str, '0abc'))

    练习:写一个正则表达式可以匹配任意一个整数字符串。例如:‘23874’, ‘-234’, ‘+2348977’

    re_str = r'[-+]?\d+' print(fullmatch(re_str, '+23874'))

    4){} {N} - 匹配N次 {M,N} - 匹配M到N次 {M,} - 匹配至少M次 {,N} - 匹配最多N次(0~N次)

    re_str = r'\d{4}abc' print(fullmatch(re_str, '6723abc')) re_str = r'a{2,5}123' print(fullmatch(re_str, 'aaaaa123')) re_str = r'a{2,}123' print(fullmatch(re_str, 'aaaaaaaaaaa123')) re_str = r'a{,2}123' print(fullmatch(re_str, 'aa123'))

    4)贪婪和非贪婪 在匹配次数不确定的情况下,匹配模式分为两种:贪婪和非贪婪 a.贪婪:默认都是贪婪的(在能匹配到的前提下匹配次数尽可能多) *、+、?, {M,N}、{M,}、{,N}

    b.非贪婪:(在能匹配到的前提下匹配次数尽可能少)在匹配次数不确定的时候,次数后面加问号,匹配就是非贪婪的 *?、+?、??、{M,N}?、{M,}?、{,N}?

    re_str = r'\d{2,}' print(search(re_str, '护士227382abc你好!')) re_str = r'\d{2,}?' print(search(re_str, '护士227382abc你好!'))

    练习:获取疫情信息中所有的国家的名字

    content = read_file('data.json') re_str = r'"provinceName":"(.+?)",' print(findall(re_str, content))

    10.5 分支和分组

    10.5.1 分支

    分支:|

    正则1|正则2|正则3...

    练习:写一个正则匹配一个字符串:123abc 和 456abc

    re_str = r'123abc|456abc' print(fullmatch(re_str, '456abc')) re_str = r'123|345abc' print(fullmatch(re_str, '123abc')) # None print(fullmatch(re_str, '123')) print(fullmatch(re_str, '345abc'))

    10.5.2 分组

    分组: ()

    1)整体操作

    实例:abc出现3次

    re_str = r'(abc){3}' print(fullmatch(re_str, 'abcabcabc'))

    实例:写一个正则匹配一个字符串:123abc 和 456abc

    re_str = r'(123|456)abc' print(fullmatch(re_str, '456abc'))

    实例:两个数字两个字母的结构重复4次: 34hj56kl67uj23Bm

    re_str = r'(\d\d[a-zA-Z]{2}){4}' print(fullmatch(re_str, '34hj56kl67uj23Bm'))

    2)重复: \M - 重复前面第M个分组匹配到的内容(M从1开始)

    re_str = r'(\d\d)=\1abc' print(fullmatch(re_str, '67=67abc')) re_str = r'(\d\d)-([a-z]{3})-\2-\1' print(fullmatch(re_str, '23-bnm-bnm-23'))

    3)捕获:findall

    转义符号: 在具有特殊功能或者特殊意义的符号前加\,让功能消失 re_str = r'\.\d\d' print(fullmatch(re_str, '.23')) re_str = r'abc\+\d\d' print(fullmatch(re_str, 'abc+34'))

    注意:独立存在有特殊功能的符号在[]中功能会自动消失

    re_str = r'[-+.]abc' print(fullmatch(re_str, '.abc'))

    10.6 re模块

    compile

    compile(正则表达式) - 编译正则表达式,创建正则表达式对象

    from re import compile, fullmatch,match,split,sub,findall,finditer,span re_obj = compile(r'\d{3}') fullmatch(r'\d{}','234') re_obj.fullmatch('234') search(r'\d{3}','dasdk234sf567') re_obj.sreach('dasdk234sf567') 匹配相关

    1)fullmatch(正则表达式,字符串) - 让整个字符串和正则表达式进行匹配

    2) match(正则表达式,字符串) - 匹配字符串开头

    如果匹配不到结果是None,如果匹配成功返回结果是匹配对象

    re_str = r'\d{3}' print(fullmatch(re_str,'732')) print(fullmatch(re_str,'732sdjk')) # None print(match(re_str,'789')) print(match(re_str,'789sakl')) 匹配对象 re_str = r'(\d{2})-([a-z]{3})' result = match(re_str,'23-sjm回款') 获取到匹配到的字符串

    匹配对象.group() - 获取整个正则表达式匹配到结果

    print(result.group()) # 23-sjm

    匹配对象.group(分组号) - 获取正则表达式中指定的分组匹配到的结果(分组号从1开始)

    print(result.group(1)) # 23 print(result.group(2)) # sjm

    2)获取匹配到的子串的范围

    匹配对象.span()

    print(result.span()) # (0,6) print(result.span(2)) # (3,6) 匹配到第二个分组的范围 获取原字符串

    匹配对象.string

    print(result.string) # 23-sjm回款 查找相关 search(正则表达式,字符串) - 在字符串中查找第一个能和正则表达式匹配的子串、如果找到了返回匹配对象,找不到返回None str1 = 'and123hu123+' print(search(r'\d+', str1))

    2)findall(正表达式,字符串) - 获取字符串中所有满足正则表达式的子串。返回一个列表,列表中的元素是字符串

    str1 = 'and123hu123+' print(findall(r'\d+', str1)) # findall正则中如果有分组,只获取分组匹配到的内容 result = findall(r'\d+[a-z]',str1) print(result) # ['123h'] result = findall(r'(\d+)[a-z]',str1) print(result) # ['123']

    3)finditer(正表达式,字符串) - 获取字符串中所有满足正则表达式的子串。返回一个迭代器,迭代器中的元素是匹配对象

    str2 = '9h3jabc===9k2mabc9293h0' result = finditer(r'((\d[a-zA-Z]){2})abc',str2) for x in result: print(x.group(1)) # 9h3j # 9k2m 切割

    split(正则表达式,字符串[,次数]) - 将字符串中能和正则表达式匹配的子串作为切割点,对字符串进行切割。返回值是列表,列表中的元素是字符串。也可以指定切割次数

    str1 = '9h3jabc===9k2mabc9293h0' result = split(r'\d+',str1) print(result) result = split(r'\d+',str1,3) print(result) 替换

    sub(正则表达式,字符串1,字符串2[,次数]) - 将字符串2中能和正则表达式匹配的子串全部替换成字符串1。也可限制替换次数。

    str1 = '9h3jabc===9k2mabc9293h0' new_str = sub(r'\d+','+',str1) print(new_str)
    Processed: 0.026, SQL: 9