一 匹配字符的符号
正则表达式就是做字符串匹配的一种工具,很多语言都支持正则语法,正则语法是通用的
python中通过re模块提供的方法来使用正则
re.fullmatch(正则表达式,字符串) ---完全匹配, 检查字符串是否满足正则表达式的要求;
如果不匹配结果是None,匹配结果是一个对象
python正则表达式 --- r'正则'
js正则表达式 --- /正则/
1 普通字符
普通字符在正则中代表字符本身,例如,a,b,1....等
要求一个字符串有5个字符,分别是h,e,l,l,o
re_str = r'hello'
result = re.fullmatch(re_str,'hello')
print(result)
2 .(匹配任意字符) 除了\n除外
- 一个.(点)匹配任意字符
匹配一个字符串有三个字符,第一个是a,第二个是任意字符,最后一个是c,
re_str = r'a.c'
result = re.fullmatch(re_str,'abc')
print(result)
3 \w(匹配字母、数字、下划线)
一个\w只能匹配一个字符
注意:这个不严谨,还可以匹配中文等字符
不能匹配ASCII码表中的出了数字,字母,下划线以外的符号
匹配一个字符串第一个字符是字母、数字、下划线,后面是abc
re_str = r'\wabc'
result = re.fullmatch(re_str,'胡abc')
print(result)
4 \s (匹配空白字符)
空白字符:空格、\t 、\n
一个\s只能匹配一个字符
匹配一个长度是8的字符,要求前三个字符是任意字符,中间两个空白字符,最后匹配三个空白字符
re_str = r'...\s\s...'
result = re.fullmatch(re_str,'abc abc')
print(result)
result = re.fullmatch(re_str,'abc\n\tabc')
print(result)
5 \d(匹配数字字符)
re_str = r'\d\dabc'
result = re.fullmatch(re_str,'12abc')
print(result)
6 \W(非数字、字母、下划线)
7 \S(非空白字符)
re_str = r'...\S\S...'
result = re.fullmatch(re_str,'abc12abc')
print(result)
8 \D(匹配非数字字符)
re_str = r'\D\Dabc'
result = re.fullmatch(re_str,'胡你abc')
print(result)
中括号(匹配字符集中的一个字符)
- a.[普通字符集] --- 匹配字符集中的任意一个字符
- b.[字符1-字符2] --- 匹配字符1到字符2中的任意一个字符(要求字符1的编码值小于字符2)
[0-9] -----匹配所有的数字
[a-z] --- 匹配小写字母
[A-Z] --- 匹配大写字母
[a-zA-Z] ---匹配所有的字母
[\da-zA-Z] --- 匹配所有的数字和字母
[\u4e00-\u9fa5] --- 匹配所有的文字
注意:一个[]只能匹配一个字符
匹配一个长度是4的字符串,第一个字符是x或者y或者z,后面是abc
re_str = r'[xyz]abc'
print(re.fullmatch(re_str,'xabc'))
匹配一个长度是4的字符串,第一个字符是x或者y或者或者数字
re_str = r'[\dxyz]abc'
print(re.fullmatch(re_str,'2abc'))
匹配一个长度是4的字符串,第一个是2到8中的一个
re_str = r'[2-8]abc'
print(re.fullmatch(re_str,'6abc'))
10 [^]
[^字符集] --- 匹配不在字符集中的任意一个字符
[^\u4e00-\u9fa5] -- 匹配一个非中文字符
二 检测字符的符号
\b(检测单词的边界)
\b --检查\b所在的位置是否是单词边界
单词边界 --- 字符串开头,字符串结尾,空白,标点符号等
匹配一个长度是4的字符串,第一个是任意字符,后边是adc;检查c的后面是否是单词边界
re_str = r'.adc\b'
print(re.fullmatch(re_str,'2adc'))
^(检查是否是字符串开头)
re_str = r'^adc'
print(re.fullmatch(re_str,'adc'))
print(re.search(r'^\d\d','as12dad'))
$(检测是否是字符串结尾)
re_str = r'^adc$'
print(re.search(r'\d\d$','as12dad'))
3.转义字符
1.转义符号:再有特殊功能、意义的符号前加‘\’,让这个正则符号变成普通符号
注意:在[]中只要不把^放在开头或者把-放在字符之间,在[]里面的字符全都可以用
re_str = r'\d\d\.\d\d'
print(re.fullmatch(re_str,'12.33'))
4.匹配次数
-
- *(匹配0次或者多次)
字符* -- 指定的字符出现0次或者多次
a* --- 字符a匹配0次或者多个
\d* --- 数字匹配0次或者多次
[a-z]* -- 小写字母匹配0次或者多次
re_str = r'a*bc'
print(re.fullmatch(re_str,'adc'))
print(re.fullmatch(re_str,'aadc'))
-
- +(匹配1次或者多次)
re_str = r'a\d+b'
# r'a\d+b'=r'a\d\d*b'
print(re.fullmatch(re_str,'a1b'))
3) ?(0次或者1次)
练习:写一个整数,能够匹配一个整数字符串
re_str = r'[-+]?\d+'
4) {}
{N} -- 匹配N次
{M,N} -- 匹配至少M次,最多N次
{M,} --匹配至少M次
{,N} --匹配最多N次
* === {0,}
+ === {1,}
? =={0,1}
5)非贪婪
贪婪 --- 匹配次数不确定的时候尽可能多的匹配(上面此时不确定的符号都是贪婪)
非贪婪 --- 匹配次数不确定的时候尽可能少的匹配(上面次数不确定的符号后面加?就会变成非贪婪)
*? --- 0次或多次,尽可能少
+? -- 1次或多次,尽可能少
?? -- 0次或1次,尽可能少
{M,N}?
{M,}?
{,N}?
re_str = r'a+'
print(re.search(re_str,'baaaac'))
re_str = r'\d{2}'
print(re.fullmatch(re_str,'12'))
re_str = r'\d{2,4}'
print(re.fullmatch(re_str,'12'))
re_str = r'[adc]{,4}'
print(re.fullmatch(re_str,'a'))
练习:写一个正则表达式判断密码是否符合要求:密码有数字和字母组成,并第一个字符是大写字母,长度是6-12位
re_str = r'[A-Z][0-9a-zA-Z]{5,11}'
5.分之和分组
|(分之)
正则1|正则2 --先用正则1匹配,如果匹配失败就用正则2匹配(正则1和正则2只要有一个匹配成功就成功,两个失败才会失败,
如果正则1成功不会匹配正则2)
匹配一个字符串,开头是abc或者xyz,后面是123
'abc','xyz'
re_str = r'abc|xyz'
print(re.fullmatch(re_str,'abc'))
print('===========')
re_str = r'\d{3}|[a-zA-Z]|\+{3}'
print(re.fullmatch(re_str,'a'))
2)() -- 分组
将部分正则作为一个整体
- 1.整体区分
result = r'(xxx|yyy)123' - 2.整体操作
re_str = r'(\d{2}[a-z]{2}){3}' - 3.整体重复
\m ---重复前面第m个分组匹配到的内容
re_str = r'(xxx|yyy)123'
print(re.fullmatch(re_str,'xxx123'))
re_str = r'(\d{2}[a-z]{2}){3}'
# 20abc20
re_str = r'(\d\d)abc\1'
# \1表示重复的第一个分组的内容
三 正则的应用
1.(了解)compile (正则表达式)-- 创建正则表达式对象
re_str = r'\d{3}'
2.fullmatch ---完全匹配
fullmatch(正则表达式,字符串) --- 让正则和字符串完全匹配;匹配失败返回None,匹配成功返回匹配对象
对整个字符串进行检查的时候使用,比如:判断账号密码是否合法,手机号,邮箱是否合法等
result = fullmatch(r'\d{3}[a-z]{2}[A-Z]{3}','123qwQWE')
print(result)
match ----匹配字符串开头
match(正则表达式,字符串) --- 让正则和字符串开头匹配;匹配失败返回None,匹配成功返回匹配对象
result = match(r'\d{3}','123asda')
print(result)
4.search -- 字符串查找
search(正则表达式,字符转)--- 在字符串中找到第一个和正则表达式匹配的子串,没有匹配到返回None。匹配到了返回对象
result = search(r'(\d{3})([A-Z]{2})','asrd122ASasd2391a')
print(result)
通过匹配对象能获得以下内容
# a.匹配结果
print(result.group()) # 获取整个正则匹配到的结果
print(result.group(1)) # 获取第一个分组匹配到的结果
# b.匹配范围(被匹配到的内容在原字符中的范围) -(开始下标,结束下标)
print(result.span())
print(result.start())
print(result.end())
# c 获取原字符串
result .string
5.split --- 字符串切割
split(正则表达式,字符串,切割次数) --- 加个字符串按照满足正则表达式的子串切割;返回的是一个列表,列表中是被切开的子串
切割次数 -- 不传参就全切
print(split(r'\d+|[A-Z]+','dasdqA2eedadZq1ad12D1adasdadqwd'))
#['dasdq', '', 'eedad', 'q', 'ad', '', '', 'adasdadqwd']
6.sub -- 字符串替换
sub(正则表达式,新的字符串,原字符串,替换次数) --- 将原字符串中满足正则表达式的子串换成新字符串
替换次数 -- 不穿参就全部替换
print(sub(r'\d+','*','asd32dsdfswfsf422dsds2wd2d'))
# asd*dsdfswfsf*dsds*wd*d
findall --- 查找所有
findall(正则表达式,字符串) ---- 在字符串中查找所有满足正则表达式的子串,以列表的形式返回
print(findall(r'\d+a','212asdad1dasd3adad3321da'))
# ['212a', '3a']
如果有分组 ,只取分组中的内容
print(findall(r'(\d+)a','212asdad1dasd3adad3321da'))
# ['212', '3']
注意:使用findall的时候,如果有分组想要取整个正则匹配的结果是取不到的
8.finditer -- 查找所有
finditer(正则表达式,字符串) ---- 在字符串中查找所有满足正则表达式的子串,返回一个迭代器,元素是每个子串对应的匹配对象
result = finditer(r'(\d[a-z]){3}\+', 'asd1a1a2+asdqdaq1a3s4d+')
print(next(result).group())
# 1a3s4d+