2021.03.24

正则表达式

from re import fullmatch

正则是一种用来处理文本数据的一种工具。(一般用于处理复杂的文本问题)

1)检测输入的数据是否是手机号?

2)检查输入的ip地址是否合法?

3)获取字符串中所有的数字数据:‘sjhfj23世纪东方和79sk试试928sjd’

正则的语法 - 用不同的符号来描述字符串规则

​ 1) 匹配类符号
​ 2) 检测类符号
​ 3) 控制次数的符号
​ 4) 分组和分支
​ 5) 其他常用参数

fullmatch(正则表达式, 字符串) - 检测字符串是否符合正则表达式描述的规则,如果不符合返回None

‘正则表达式’ - Python “正则表达式” - OC/python /正则表达式/ - js

匹配类符号 - 一个符号对应字符串的一个字符

1)普通字符 - 特殊符号以外的字符就是普通字符

普通字符在正则中表示这个符号本身

re_str = 'abc'     # 需要一个长度是3的字符串,并且第一个字符是a, 第二个字符是b, 第三个字符是c
print(fullmatch(re_str, 'abc'))

. - 匹配一个任意字符

re_str = 'a.c'    # 需要一个长度是3的字符串, 并且第一个字符是a, 最后一个字符是c,中间是任意字符
print(fullmatch(re_str, 'a胡c'))re_str = '..ab'  # 一个长度是4的字符串,ab前面是任意两个字符
print(fullmatch(re_str, 'o9ab'))

\d - 匹配任意一个数字字符

re_str = r'ab\d'    # 一个长度是3的字符串,ab后面是一个任意数字
print(fullmatch(re_str, 'ab3'))

\w - 匹配任意一个数字、字母或者下划线(基于ASCII码)

re_str = r'\w123'
print(fullmatch(re_str, '好123'))

\s - 匹配任意一个空白字符

空白字符 - 空格、\t、\n

re_str = r'123\sabc'
print(fullmatch(re_str, '123 abc'))

\D、\S、\W

# \D    -   匹配任意一个非数字字符
# \S    -   匹配任意一个非空白字符
print(fullmatch(r'abc\S123\D', 'abcM123='))

[字符集] - 匹配字符集中的任意一个字符

[ab12] - 匹配a、b、1或者2中任意一个字符
[ab\d]、[\dab]、[a\db]、[ab0123456789] - 匹配a、b、或者0到9中任意一个字符
[0-9] - 匹配0到9中任意一个字符
[56789]、[5-9] - 匹配5到9中任意一个字符
[a-z] - 匹配任意一个小写字母
[A-Z] - 匹配任意一个大写字母
[a-zA-Z] - 匹配任意一个字母
[a-zA-Z\d_] - 匹配任意一个字母、数字、下划线
[\u4e00-\u9fa5] - 匹配任意一个中文

注意:如果[]中-在两个字符之间表示范围,如果-不在两个字符之间,它不具备特殊功能表示这个符号本身, -在[]外面也是普通符号

re_str = r'a[xyz]b'
print(fullmatch(re_str, 'ayb'))print(fullmatch(r'abc[2-5]', 'abc4'))print(fullmatch(r'[\u4e00-\u9fa5]abc', '好abc'))
# print(fullmatch(r'[z-a]abc', 'wabc'))   # 报错print(fullmatch(r'[ac-]123', '-123'))

[^字符集] - 匹配除了字符集以外的任意一个字符

print(fullmatch(r'[^axy]123', 'k123'))
print(fullmatch(r'[^a-zA-Z]123', '-123'))

注意:[]里面,只有放在最前面才有特殊意义,在其他位置表示本身

print(fullmatch(r'[a-z^]123', '^123'))

检测类符号

在正则中不会影响字符串长度,它们的作用是在匹配成功以后检测检测类符号所在的位置是否符号要求

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

单词边界 - 凡是能够将两个单词区分开的所有的符号,主要有:空白、标点符号、字符串开头和字符结尾

re_str = r'abc \b123'
print(fullmatch(re_str, 'abc 123'))re_str = r'abc\b.123'
print(fullmatch(re_str, 'abc,123'))str1 = '数据集,890,shs323节省时间34jsj 922 失敬失8敬283'
result = findall(r'\b\d+\b', str1)
print(result)

\B - 检测是否不是单词边界

result = findall(r'\B\d+\B', str1)
print(result)

^ - 检测是否是字符串开头([]外面)

$ - 检测是否是字符串结尾([]外面)

re_str = r'\dabc$'
print(findall(re_str, '7abc啥时间2abc数据9abc是6abc'))

匹配次数

*- 匹配0次或多次

a* - 匹配0个或者多个a
.* - 匹配0个或者多个任意字符
\d* - 相当于任意多个\d
[xyz]* - 相当于任意多个[xyz]

re_str = r'a*123'
print(fullmatch(re_str, 'aaaaaa123'))re_str = r'.*123'
print(fullmatch(re_str, 'asc123'))re_str = r'\d*abc'
print(fullmatch(re_str, '78908887abc'))re_str = r'[xyz]*123'
print(fullmatch(re_str, 'xxyz123'))

± 1次或者多次

? - 0次或者1次

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

print(fullmatch(r'\d{3}abc{5}', '722abccccc'))
print(fullmatch(r'\d{3,5}abc', '72126abc'))
print(fullmatch(r'\d{,2}abc', '23abc'))
print(fullmatch(r'\d{2,}abc', '2231abc'))

练习:写程序判断输入手机号是否合法:1)长度11位 2)都是数字 3)第一位必须是1,第二位是3~9

def is_tel(tel: str):result = fullmatch(r'1[3-9]\d{9}', tel)if result:print(f'{tel}是合法的手机号')else:print(f'{tel}不是合法的手机号')is_tel('17865754346')

贪婪和非贪婪

贪婪和非贪婪模式是在匹配次数不确定的时候才会出现:*、+、?、{M,N}、{,N}、{M,}
贪婪和非贪婪:在能够匹配成功的情况下,如果对应的匹配次数有多种,贪婪模式选最多的那个次数,非贪婪选最少的那个次数。

贪婪:、+、?、{M,N}、{,N}、{M,}
非贪婪:
?、+?、??、{M,N}?、{,N}?、{M,}?

print(search(r'\d{3}', 'shsj234色即是空889====902'))    # <re.Match object; span=(4, 7), match='234'>re_str = r'a.+b'
print(search(re_str, '试试amnbxyzb是计算机数据'))    # <re.Match object; span=(2, 10), match='amnbxyzb'>re_str = r'a.+?b'
print(search(re_str, '试试amnbxyzb是计算机数据'))    # <re.Match object; span=(2, 6), match='amnb'>re_str = r'a.+b'
print(search(re_str, '试试amnbxyz是计算机数据'))    # <re.Match object; span=(2, 6), match='amnb'>response = requests.get('http://api.tianapi.com/txapi/ncovabroad/index?key=c9d408fefd8ed4081a9079d0d6165d43')
result = findall(r'"provinceName":"([\u4e00-\u9fa5]+?)"', response.text)
print(result)

分组和分支

分组

应用一:将正则表达式中的一部分用()括起来表示一个整体,然后进行整体相关操作
应用二:通过\M来重复它前面第M个分组匹配到的内容
应用三:捕获(获取结果的时候只取某个分组对应的内容)

# hj78hu23kk90
re_str = r'([a-zA-Z]{2}\d\d){3}'
print(fullmatch(re_str, 'hj78hu23kk90'))
# mn123mn、xy123xy
re_str = r'([a-z]{2})123\1'
print(fullmatch(re_str, 'mn123mn'))re_str = r'(\d{2})([A-Z]{3})\1\2'
print(fullmatch(re_str, '12MNA12MNA'))
re_str = r'(\d{2})([A-Z]{3})\1{2}\2'
print(fullmatch(re_str, '12KAM1212KAM'))re_str = r'[a-z](\d{3})'
result = findall(re_str, 'hsjs234失敬失敬你a8393sjjk9901啥时间---234看看嘛238')
print(result)

分支 - |

正则1|正则2

|相当于或者

# abc123、abcMN
re_str = r'abc\d{3}|abc[A-Z]{2}'
print(fullmatch(re_str, 'abcMN'))re_str = r'abc\d{3}|[A-Z]{2}'
print(fullmatch(re_str, 'MK'))re_str = r'abc(\d{3}|[A-Z]{2})'
print(fullmatch(re_str, 'abc234'))

re模块

from re import *

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

re_obj = compile(r'\d{3}')print(fullmatch(r'\d{3}', '234'))
print(re_obj.fullmatch('384'))

匹配相关方法

1)fullmatch(正则表达式, 字符串) - 完全匹配,判断整个字符串是否符合正则表达式描述的规则。如果不符合返回None,如果符合返回匹配对象

2)match(正则表达式, 字符串) - 匹配开头,判断字符串开头是否符合正则表达式描述的规则。如果不符合返回None,如果符合返回匹配对象

re_str = r'[a-z]{3}'
print(fullmatch(re_str, 'hsm'))
print(match(re_str, 'mks结束的发就好为34'))

3)匹配对象

re_str = r'((\d{2})([A-Z]{3}))'
result = match(re_str, '23KLA失敬失敬')
print(result)

匹配对象.group() / 匹配对象.group(0) - 获取整个正则匹配到的内容

匹配对象.group(N) - 获取正则表达式第N个分组匹配到的内容

print(result.group())     # '23KLA'
print(result.group(1))    # '23KLA'
print(result.group(2))      # '23'
print(result.group(3))      # 'KLA'

匹配对象.span() / 匹配对象.span(0) - 获取整个正则匹配到的内容在原字符串中的位置信息(开始下标和结束下标)

匹配对象.span(N) - 获取正则表达式第N个分组匹配到的内容在原字符串中的位置信息

print(result.span())
print(result.span(3))

匹配对象.string - 获取原字符串

print(result.string)   # '23KLA失敬失敬'

查找相关方法

  1. search(正则表达式, 字符串) - 在字符串中搜索第一个满足正则表达式的字符串。如果找不到返回None,找到了返回匹配对象
print(search(r'\d{3}', '试试234节省时间988开始时间210'))    # <re.Match object; span=(2, 5), match='234'>
  1. findall(正则表达式, 字符串) - 获取字符串中所有满足正则表达式的子串。返回值是列表,如果找不到返回空列表
print(findall(r'\d{3}', '试试234节省时间988开始时间210'))    # ['234', '988', '210']
print(findall(r'\d{3}[\u4e00-\u9fa5]', '试试234节省时间988开始时间210mn'))   # ['234节', '988开']
print(findall(r'(\d{3})[\u4e00-\u9fa5]', '试试234节省时间988开始时间210mn'))   # ['234', '988']
print(findall(r'\d{3}-[a-z]{2}', '啥时间233-ks试试,892-mk啥,sjs2912-op'))  # ['233-ks', '892-mk', '912-op']
print(findall(r'(\d{3})-([a-z]{2})', '啥时间233-ks试试,892-mk啥,sjs2912-op'))   # [('233', 'ks'), ('892', 'mk'), ('912', 'op')]
print(findall(r'(\d[a-z]){3}', '是计算机上8m9l0b,s数据是8a0p1k'))    # ['0b', '1k']
  1. finditer(正则表达式, 字符串) - 获取字符串中所有满足正则表达式的子串。返回一个迭代器,迭代器中的元素是匹配对象
result = finditer(r'(\d{3})-([a-z]{2})', '啥时间233-ks试试,892-mk啥,sjs2912-op')
# print([x.group() for x in result])    # ['233-ks', '892-mk', '912-op']
# print([x.group(1) for x in result])     # ['233', '892', '912']
print([x.group(2) for x in result])       # ['ks', 'mk', 'op']
  1. sub(正则表达式, 字符串1, 字符串2) - 将字符串2中所有满足正则的子串全部替换成字符串
str1 = 'how are you? I am fine, Thank you!'
result = sub(r'you', 'me', str1)
print(result)    # how are me? I am fine, Thank me!str1 = 'how are you? I am fine, Thank you!'
result = sub(r'you|I', 'me', str1)
print(result)   # how are me? me am fine, Thank me!result = sub(r'傻[\s/,.\\]*[b瓜]|f\s*u\s*c\s*k|操', '*', r'我操, 你是傻    /b吗?F u c k')
print(result)
  1. split(正则表达式, 字符串) - 将字符串中所有满足正则表达式的子串作为切割点对字符串进行切割
result = split(r'[-+]', '试试-j234ss+skskj-健康是390福+世纪东2方看019计算机')
print(result)result = split(r'\d+', '试试-j234ss+skskj-健康是390福+世纪东2方看019计算机')
print(result)

转义符号

from re import fullmatch, I, S

转义符号 - 将在正则中有特殊功能或者意义的符号变成一个普通字符

\具有特殊意义的符号: .、+、*、…

re_str = r'\d{2}\.\d{2}'
print(fullmatch(re_str, '23.34'))re_str = r'\\dabc\+'
print(fullmatch(re_str, '\dabc+'))re_str = r'\(\d{2}\)'
print(fullmatch(re_str, '(23)'))

将独立存在具备特殊功能的符号放在[]里面,这个符号的功能会自动消失

特别注意符号在[]里面也有特殊功能的情况,比如:^、-、[、]

re_str = r'\d{2}[.+?*(\-)|$^\]]\d{2}'
print(fullmatch(re_str, '23]34'))

常用参数

1)忽略大小写

默认不忽略大小写

print(fullmatch(re_str, '123k'))   # <re.Match object; span=(0, 4), match='123k'>
print(fullmatch(re_str, '123M'))   # None

用法一: r’(?i)正则表达式’

re_str = r'(?i)123[a-z]'
print(fullmatch(re_str, '123k'))   # <re.Match object; span=(0, 4), match='123k'>
print(fullmatch(re_str, '123M'))    # <re.Match object; span=(0, 4), match='123M'>
re_str = r'123[a-z]'
print(fullmatch(re_str, '123M', flags=I))    # <re.Match object; span=(0, 4), match='123M'>

单行匹配

多行匹配(默认) - 表示任意字符的.不能和\n(换行符)进行匹配
单行匹配 - 表示任意字符的.可以和\n(换行符)进行匹配

re_str = r'abc.123'
print(fullmatch(re_str, 'abc\n123'))    # None

用法一

re_str = r'(?s)abc.123'
print(fullmatch(re_str, 'abc\n123'))   # <re.Match object; span=(0, 7), match='abc\n123'>
re_str = r'abc.123'
print(fullmatch(re_str, 'abc\n123', flags=S))   # <re.Match object; span=(0, 7), match='abc\n123'>
re_str = r'(?is)abc.123'
print(fullmatch(re_str, 'ABC\n123'))    # <re.Match object; span=(0, 7), match='ABC\n123'>re_str = r'abc.123'
print(fullmatch(re_str, 'ABC\n123', flags=I | S))   # <re.Match object; span=(0, 7), match='ABC\n123'>

作业

一、不定项选择题

  1. 能够完全匹配字符串"(010)-62661617"和字符串"01062661617"的正则表达式包括(c )

A.r"\(?\d{3}\)?-?\d{8}"
B. r"[0-9()-]+"
C.r"[0-9(-)]*\d*"
D.r"[(]?\d*[)-]*\d*"

  1. 能够完全匹配字符串“c:\rapidminer\lib\plugs”的正则表达式包括( )
    A. “c:\rapidminer\lib\plugs”
    B. “c:\rapidminer\lib\plugs”
    C. “(?i)C:\RapidMiner\Lib\Plugs” ?i:将后面的内容的大写变成小写
    D. “(?s)C:\RapidMiner\Lib\Plugs” ?s:单行匹配
  2. 能够完全匹配字符串“back”和“back-end”的正则表达式包括( A BCD)
    A. “\w{4}-\w{3}|\w{4}”
    B. “\w{4}|\w{4}-\w{3}”
    C. “\S±\S+|\S+”
    D. “\w*\b-\b\w*|\w*”
  3. 能够完全匹配字符串“go go”和“kitty kitty”,但不能完全匹配“go kitty”的正则表达式包括(AD)
    A. “\b(\w+)\b\s+\1\b”
    B. “\w{2,5}\s*\1”
    C. “(\S+) \s+\1”
    D. “(\S{2,5})\s{1,}\1”
  4. 能够在字符串中匹配“aab”,而不能匹配“aaab”和“aaaab”的正则表达式包括(B C)
    A. “a*?b”
    B. “a{,2}b”
    C. “aa??b”
    D. “aaa??b”

二、编程题

1.用户名匹配

​ 要求: 1.用户名只能包含数字 字母 下划线

​ 2.不能以数字开头

​ 3.⻓度在 6 到 16 位范围内

from re import *def new_names(str1):result=fullmatch(r'[^0-9]\w.{6,16}',str1)if result:print(f'正确')else:print(f'错误')new_names('1amsdka;ls')
  1. 密码匹配

​ 要求: 1.不能包含!@#¥%^&*这些特殊符号

​ 2.必须以字母开头

​ 3.⻓度在 6 到 12 位范围内

def new_pw(str1):result=fullmatch(r'[a-zA-Z]([0-9]|[a-zA-Z]|[\u4e00-\u9fa5]){6,12}',str1)if result:print(f'正确')else:print(f'错误')new_pw('aslas好uja')
  1. ipv4 格式的 ip 地址匹配
    提示: IP地址的范围是 0.0.0.0 - 255.255.255.255

  1. 提取用户输入数据中的数值 (数值包括正负数 还包括整数和小数在内) 并求和
例如:“-3.14good87nice19bye” =====> -3.14 + 87 + 19 = 102.86
def re_data(str1:str):result=findall(r'[-]?\d[.]?\d+',str1)s=[]for x in result:s.append(float(x))return ss=re_data('-3.14good87nice19bye')
print(sum(s))
  1. 验证输入内容只能是汉字

    def names(str1):result=fullmatch(r'[\u4e00-\u9fa5]+',str1)if result:print(f'输入正确')else:print(f'输入错误')names('哈斯卡')
    
  2. 匹配整数或者小数(包括正数和负数)

    def nums(str1):result=fullmatch(r'-?\d+(\.\d+)?',str1)if result:print(f'正确')else:print(f'错误')nums('-3.89')
    
  3. 验证输入用户名和QQ号是否有效并给出对应的提示信息

    要求:
    用户名必须由字母、数字或下划线构成且长度在6~20个字符之间
    QQ号是5~12的数字且首位不能为0

    def names_pw(str1,str2):result1=fullmatch(r'\w{6,20}',str1)result2=fullmatch(r'[^0]\d{5,12}',str2)if result1 and result2:print(f'输入正确')else:print(f'输入错误')names_pw('jasd221','0178237')
    
  4. 拆分长字符串:将一首诗的中的每一句话分别取出来

    ​ poem = ‘窗前明月光,疑是地上霜。举头望明月,低头思故乡。’

def extract(str1:str):result=findall(r'[\u4e00-\u9fa5]{5}',str1)return results=extract('窗前明月光,疑是地上霜。举头望明月,低头思故乡。')
print(s)

2021.03.24正则匹配符号相关推荐

  1. 珍藏网站集合——更新于2021.03.24

    文章目录 学习网站 视频网站 语言/框架官方文档 社区平台 前端网站 资源下载 源代码下载 软件下载 素材下载 网盘资源 电脑游戏 工具 文档工具 编程工具 素材加工制作 我的平台 大全网 学习网站 ...

  2. 2021.3.24 正则表达式

    总结 01正则匹配符号 什么是正则(正则表达式) 正则是一种用来处理文本数据的一种工具.(一般用于处理复杂的文本问题) 1)检测输入的数据是否是手机号? 2)检查输入的ip地址是否合法? 3)获取字符 ...

  3. 正则匹配中英文全部特殊符号

    正则匹配中英文全部特殊符号 ((?=[\x21-\x7e]+)[^A-Za-z0-9])|[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001 ...

  4. html正则半角,JS正则密码校验之:JS正则匹配半角英文符号

    概述 在JS密码重网有剑据些文页的底社按标近新站的不的方校验中常常会遇到密码强度的校验需求,借用一位朋友提问的图,他在工作中遇到的一个比较经典的密码强度校验要和第,.年过事工宗据指数遍互业经搞断果会击 ...

  5. JS正则密码校验之:JS正则匹配半角英文符号

    概述 在JS密码校验中常常会遇到密码强度的校验需求,借用一位朋友提问的图,他在工作中遇到的一个比较经典的密码强度校验要求: 这个需求有两个难点,一,是如何使用正则匹配所有半角英文标点符号,二,是如何验 ...

  6. 正则匹配之正则匹配全部汇总:

    正则匹配全部汇总: 1.匹配中文:[\u4e00-\u9fa5] 2.英文字母:[a-zA-Z] 3.数字:[0-9] 4.匹配中文,英文字母和数字及下划线:^[\u4e00-\u9fa5_a-zA- ...

  7. js正则匹配可见字符

    正则匹配可见字符 数字大小写字母特殊符号 原理 ascii码33-126为可见字符,对应16进制为x21-x7e var str="agdggd#$%$^234"; patt=/[ ...

  8. 常用正则匹配及字符范围

    编程中有时候需要用到匹配中文的正则,一般用 [ \u4e00-\u9fa5]+ 即可搞定.不过这正则对一般的火星文鸟语就不太适用了,甚至全角的标点符号都不包含在内.例如游戏里面的玩家名,普通青年一般都 ...

  9. Nginx rewrite正则匹配重写

    Nginx的rewrite功能支持正则匹配重写,即将URL地址临时或永久重新指向某个新的位置,类似于重定向.这个特性有利用当网站结构做出重大调整,如之前的网站mp3资源使用URL为www.site1. ...

最新文章

  1. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头3
  2. 高级转录组分析和R语言数据可视化第十三期 (线上线下同时开课)
  3. 如果重走职场,一定会送自己 8 个锦囊
  4. Flutter底部导航栏BottomNavigationBar
  5. [转]JSP中EL表达式三元运算符的使用
  6. Python中Function(函数)和method(方法)
  7. testng.xml文件配置
  8. 企业级应用架构(一) 三层架构之解耦
  9. java 文件大小统计工具类_Java获取文件大小,文件夹内文件个数的工具类
  10. CentOS7 设置防火墙端口
  11. combobox is not a function 问题解决
  12. centos下查看最大Socket连接数
  13. SpringBoot2注解配置定时任务和异步执行任务
  14. 计算机视觉算法与应用汇总
  15. CAD导入arcgisMap进行shp导出异常现象
  16. JS判断数组是否相同
  17. 基于HAL库的STM32F704的电阻式触摸屏的学习
  18. 网络直播对网络的要求有多高
  19. Letter to a newborn son
  20. 使用切换器导致一台电脑分辨率被降低的解决方法

热门文章

  1. 硅谷创业教父保罗•格雷厄姆给小白的创业建议书
  2. background-size cover和contain的区别
  3. java和c++复试面试题
  4. Chocolate 一万粉成就达成 | 对未来工作内容的考虑,也许我会选择不做开发了
  5. 学习Accelerated C++1
  6. 客厅装修应注意空间的布局
  7. 今天生日,还要在家远程上班。你们公司什么情况?
  8. SecureCRT初次使用
  9. 优雅的使用Onedrive推送书籍到Kindle
  10. vue 组件封装 确认弹框带可以自定义titile ,内容,和取消,确定按钮的弹窗 slot插槽