re模块
【1】引入
# 必须是 11 位,并且是数字 ,必须符合国家规范 # 正常情况下 def check_phone_number(phone): # 必须是11位 if len(phone) != 11: print(f"手机号位数错误") else: # 必须全是数字 if not phone.isdigit(): print(f"格式错误") else: # 必须符合规范 # 校验开头是否合法 if phone.startswith('13') or phone.startswith('15') or phone.startswith('17') or phone.startswith('18'): print(f"正常") else: print(f"不正常") phone = input("phone:") check_phone_number(phone) # 正则方法 import re def check_phone_number(phone_number): if re.match('^(13|15|17|18)[0-9]{9}$', phone_number): print('yes') else: print('no') phone = input("phone:").strip() check_phone_number(phone_number=phone)
【2】字符组
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
[0123456789] | 8 | True | 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 |
[0123456789] | a | False | 由于字符组中没有"a"字符,所以不能匹配 |
[0-9] | 7 | True | 也可以用-表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] | s | True | 同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] | B | True | [A-Z]就表示所有的大写字母 |
[0-9a-fA-F] | e | True | 可以匹配数字,大小写形式的a~f,用来验证十六进制字符 |
-
字符组就是在同一个位置可能出现的字符
-
字符组用 []
-
字符组的[备选项] 字母、数字、特殊标点
(1)匹配0-9数字
import re pattern = "[0123456789]" res = re.findall(pattern, 'abcdef12356978') print(res) # ['1', '2', '3', '5', '6', '9', '7', '8']
(2)匹配小写字母
import re pattern = "[a-z]" res = re.findall(pattern,'12341abc21kh') print(res) # ['a', 'b', 'c', 'k', 'h']
(3)匹配大写字母
import re pattern = "[A-Z]" res = re.findall(pattern,'1234ACD1abcO21KUJkh') print(res) # ['A', 'C', 'D', 'O', 'K', 'U', 'J']
(4)大小写字母+数字混合
import re pattern = "[A-Za-z0-9]" res = re.findall(pattern,'1,234ACD1abcO21KUJkh') print(res) # ['1', '2', '3', '4', 'A', 'C', 'D', '1', 'a', 'b', 'c', 'O', '2', '1', 'K', 'U', 'J', 'k', 'h']
【3】元字符
元字符 | 匹配内容 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a|b | 匹配字符a或字符b |
() | 匹配括号内的表达式,也表示一个组 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中字符的所有字符 |
(1). 代表除换行以外的任意字符
import re kin = 'abcnHIMN1456' pattern = "." res = re.findall(pattern, kin) print(res) # ['a', 'b', 'c', 'n', 'H', 'I', 'M', 'N', '1', '4', '5', '6']
(2)\w 代表数字或者字母或下划线
import re kin = 'abcnHIMN1456,_;$' pattern = "\w" res = re.findall(pattern, kin) print(res) # ['a', 'b', 'c', 'n', 'H', 'I', 'M', 'N', '1', '4', '5', '6', '_']
(3)\s 代表任意的空白符 ---> 空格
import re kin = 'abcn HI MN1456,_;$' pattern = "\s" res = re.findall(pattern, kin) print(res) # [' ', ' ']
(4)\d 只能匹配数字
import re kin = 'abcn HI MN1456,_;$' pattern = "\d" res = re.findall(pattern, kin) print(res) # ['1', '4', '5', '6']
(5)\W 除了字母或数字或者下划线以为的任意字符
import re kin = 'abcn HI MN1456,_;$' pattern = "\W" res = re.findall(pattern, kin) print(res) # [' ', ' ', ',', ';', '$']
(6)\n 只能匹配换行符
import re kin = ''' abc n HI M N1456,_;$ ''' pattern = "\n" res = re.findall(pattern, kin) print(res) # ['\n', '\n', '\n', '\n']
(7)\t 制表符
import re kin = 'abcn HI M%N1456,_;$' pattern = "\t" res = re.findall(pattern, kin) print(res) # []
(8)\b 匹配一个单词的结尾
(9)^字符 以某个字符开头
import re kin = 'bcn HI M%cbNkb456,_;$' pattern = "^b" res = re.findall(pattern, kin) print(res) # ['b']
(10)字符$ 以某个字符结尾
kin = 'bcn HI M%cbNkb456,_;$kh' pattern = "h$" res = re.findall(pattern, kin) print(res) # ['h']
(11)\D 匹配除数字以外的任意字符
import re kin = 'bcn HI M%N456,_;$kh' pattern = "\D" res = re.findall(pattern, kin) print(res) # ['b', 'c', 'n', ' ', 'H', 'I', ' ', 'M', '%', 'N', ',', '_', ';', '$', 'k', 'h']
(12)\S 匹配除空格以外的所有字符
import re kin = 'bcn HI M%N456,_;$kh' pattern = "\S" res = re.findall(pattern, kin) print(res) # ['b', 'c', 'n', 'H', 'I', 'M', '%', 'N', '4', '5', '6', ',', '_', ';', '$', 'k', 'h']
(13)字符|字符 匹配任意一个字符
import re kin = 'bcn HI M%N456,_;$kh' pattern = "b|c|4|," res = re.findall(pattern, kin) print(res) # ['b', 'c', '4', ',']
(14)() 声明优先级
import re kin = 'bcn H 2I M%N 4b 56,4_;$kh' pattern = "\d(\w)" # 以数字开头,数字字母或下划线结尾 res = re.findall(pattern, kin) print(res) # ['I', 'b', '6', '_']
(15)字符组
import re kin = 'bcn H 2I M%N 4b 56,4_;$kh' pattern = "[a-z0-9A-Z][0-9]" # [大小写和数字都可以,只能数字] res= re.findall(pattern,kin) print(res) # ['56']
import re kin = 'bcn H 2I M%N 4b 56,4_;$kh' pattern = "[^a-z0-9A-Z][0-9]" res= re.findall(pattern,kin) print(res) # [' 2', ' 4', ' 5', ',4']
【4】量词
量词 | 用法说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
(1)* 代表当前字符重读零次或更多次
import re pattern = "[0-9][a-z]*" kin = 'a b c de$f_g hi jk AB C D E AA bb 5a b6 111 6de,_;' res = re.findall(pattern, kin) print(res) # ['5a', '6', '1', '1', '1', '6de'] 前面是数字,后面是小写字母可重读0-n次
(2)+ 代表当前字符重读一次或者更多次
import re pattern = "[0-9][a-z]+" kin = 'a b c de$f_g hi jk AB C D E AA bb 5a b6 111 6de,_;' res = re.findall(pattern, kin) print(res) # ['5a', '6de'] 前面是数字,后面是小写字母 可重读1-n次
(3)? 重复零次或一次
import re pattern = "[0-9][a-z]?" kin = 'a b c de$f_g hi jk AB C D E AA bb 5a b6 111 6de,_;' res = re.findall(pattern, kin) print(res) # ['5a', '6', '1', '1', '1', '6d'] 前面是数字,后面是小写字母 可重读0或1次
(4){n} 重复n次
import re pattern = "[0-9][a-z]{3}" kin = 'a b c de$f_g hi jk AB C D5kjnh E AA bb 5aeca b6 111 6de,_;' res = re.findall(pattern, kin) print(res) # ['5kjn', '5aec'] 前面是数字,后面是小写字母 必须匹配重读3次
(5){n,m}重复至少n次 至多m次
import re pattern = "[0-9][a-z]{1,3}" kin = 'a b c de$f_g hi jk AB C D5kjnh E AA bb 3u 8y 5aeca b6 111 6de,_;' res = re.findall(pattern, kin) print(res) # ['5kjn', '3u', '8y', '5aec', '6de'] 前面是数字,后面是小写字母 可以匹配重读1-3次
【5】位置元字符
-
. 代表任意字符
import re pattern = "海." kin = '''海燕海娇海东海冬梅''' res = re.findall(pattern, kin) print(res) # ['海燕', '海娇', '海东', '海冬']
-
. 代表任意字符
-
^ 以...开头
import re pattern = "^海." kin = '''海燕海娇海东海冬梅''' res = re.findall(pattern, kin) print(res) # ['海燕']
-
. 代表任意字符
-
$ 代表以...结尾
import re pattern = "海.$" kin = '海燕海娇海东海冬' res = re.findall(pattern, kin) print(res) # ['海冬']
-
. 代表任意字符
-
? 重复零次或一次
import re pattern = "李.?" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res) # ['李杰', '李莲', '李二']
-
. 代表任意字符
-
*
重复零次或者更多次
import re pattern = "李.*" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res) # ['李杰李莲英和李二棍子']
-
. 代表任意字符
-
+
重复一次或更多次
import re pattern = "李.+" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res) # ['李杰李莲英和李二棍子']
-
. 代表任意字符
-
{m,n} 重复一次或更多次
import re pattern = "李.{2,3}" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res) # ['李杰李莲', '李二棍子']
-
. 代表任意字符
-
[] 字符组中的任意一个
import re pattern = "李[杰莲英二棍子]" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res) # ['李杰', '李莲', '李二'] 从字符组匹配,匹配到一个 后面的就不会再管了
-
. 代表任意字符
-
[] 字符组中的任意一个
-
^ 和 除了和
-
*任意
import re pattern = "李[^和]*" kin = '李杰李莲英和李二棍子' res = re.findall(pattern, kin) print(res)
【6】分组匹配
-
| 或条件
-
() 优先匹配
-
[^] 除了当前字符以外的其他字符
【7】贪婪匹配
-
贪婪匹配:在满足匹配时,匹配尽可能长的字符串, 默认情况下,采用贪婪匹配
-
非贪婪匹配:在满足匹配时,匹配尽可能少的字符串
-
常用的非贪婪匹配,pattern
-
*? 重复任意次,但尽可能少重复
-
+? 重复1次或更多次,但尽可能少重复
-
?? 重复0次或1次,但尽可能少重复
-
{n,m}? 重复n到m次,但尽可能少重复
-
{n,}? 重复n次以上,但是尽可能少重复
【8】方法
(1)findall
-
返回所有满足匹配条件的结果,放在列表中
import re sen = "Knight is a good person." pattern = "i" result = re.findall(pattern, sen) print(result) # ['i', 'i']
(2)search
-
只匹配到符合条件的一个字符
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象 # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。 import re sen = "Knight is a good person." pattern = "i" result = re.search(pattern, sen) print(result) result = re.search(pattern,sen).group() print(result)
(3)match
# 在开头匹配 import re sen = "Knight is a good person." pattern = "K" result = re.match(pattern, sen) print(result) result = re.match(pattern,sen).group() print(result) # <re.Match object; span=(0, 1), match='K'> # K
(4)split
-
先按"a"分割得到 '空格' 和 'bcd' ,再对 '空格' 和 'bcd' 分别按 'b' 分割
import re kin = 'abcd' pattern = '[ab]' result = re.split(pattern,kin) print(result) # ['', '', 'cd']
(5)sub
-
默认替换所有匹配到的字符,可以用count控制替换次数
import re kni = 'ev4ak5jda4da6' # 将数字替换成'K',参数1表示只替换1个 # 默认替换所有匹配到的字符 pattern = '\d' result = re.sub(pattern, 'K',kni) result1 = re.sub(pattern, 'K',kni,count=2) print(result) # evKakKjdaKdaK print(result1) # evKakKjda4da6
(6)subn
-
替换匹配到的所有字符并返回 替换成功的字符和替换次数
import re kni = 'ev4ak5jda4da6' # 将数字替换成'K',返回一个元组(替换的结果,替换的次数) result = re.subn('\d', 'K',kni) print(result) # ('evKakKjdaKdaK', 4)
(7)compile
-
预编译正则表达式
import re kni = 'ev456ak5jda4da6' obj = re.compile('\d{3}') print(obj) ret = obj.search(kni) print(ret.group()) # 456 print(re.findall(obj, kni)) # ['456']
【9】正则方法优先级
(1)findall的优先级查询
import re pattern = 'www.(baidu|oldboy).com' pattern = re.compile(pattern) data = 'www.oldboy.com' ret = re.findall(pattern, data) # 在pattern中优先匹配data print(ret) # ['oldboy'] ret1 = re.findall('www.(?:baidu|oldboy).com', 'www.baidu.com') # 优先匹配baidu print(ret1) # ['www.baidu.com']
(2)split的优先级查询
-
在匹配部分加上()之后所切出的结果是不同的
-
没有()的 没有保留所匹配的项,但是有()的却能够保留匹配的项
-
这个在某些需要保留匹配部分的使用过程是非常重要的
import re ret = re.split("\d+","ev456ak5jda4da6") print(ret) # ['ev', 'ak', 'jda', 'da', ''] ret = re.split("(\d+)","ev456ak5jda4da6") print(ret) # ['ev', '456', 'ak', '5', 'jda', '4', 'da', '6', '']
【10】常用的正则表达式
场景 | 正则表达式 |
---|---|
用户名 | ^[a-z0-9_-]{3,16}$ |
密码 | ^[a-z0-9_-]{6,18}$ |
手机号码 | ^(?:\+86)?1[3-9]\d{9}$ |
颜色的十六进制值 | ^#?([a-f0-9] |
电子邮箱 | ^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+\.[a-z]+$ |
URL | ^(?:https:// |
IP 地址 | ((2[0-4]\d |
HTML 标签 | ^<([a-z]+)([^<]+)*(?:>(.*)<\/\1> |
utf-8编码下的汉字范围 | ^[\u2E80-\u9FFF]+$ |