一、正则表达式
正则表达式:用来做字符串查找、匹配、切割的一种工具
python对正则表达式的支持:提供了re模块(python内置模块),包含字符串匹配、查找、切割等相关方法
fullmatch(正则表达式,字符串):用正则表达式来和字符串进行匹配,看是否能够成功
正则表达式:是一个符&正则规范的字符串
import re
if __name__ == '__main__':
# re.fullmatch()
(注意:正则表达式的字符串,前面一般要加r,来阻止转义,因为正则表达式的符号中,有很多带'\'的符号,
其功能不是转义,而是表示特殊的意义)
"""
(1) . :匹配一个任意字符
re_str='..' :匹配两个任意字符的字符串
re_str='ab' :匹配第一个字符是a,第二个字符是b的字符串
re_str='a.' :匹配第一个字符是a,第二个字符是任意字符的字符串
"""
re_str = '.'
print(re.fullmatch(re_str, 'a')) # <_sre.SRE_Match object; span=(0, 1), match='a'>
"""
(2) \w:匹配一个字符是字母、数字、下划线
re_str=r'\w\w':匹配第一个字符是字母数字下划线,第二个字符也是字母数字下划线
"""
re_str = r'\w'
print(re.fullmatch(re_str, '_')) # <_sre.SRE_Match object; span=(0, 1), match='_'>
re_str = r'\w.\w'
print(re.fullmatch(re_str, '2)n')) # <_sre.SRE_Match object; span=(0, 3), match='2)n'>
"""
(3) \s:匹配一个空白字符(空格,换行,制表符)
re_str=r'a\sb':匹配第一个字符是a,第二个字符是空格,换行,制表符,第三个字符是b 的字符串
"""
re_str = r'a\sb'
print(re.fullmatch(re_str, 'a b')) # 'a\tb' ,'a\nb','a b','a b'
"""
(4) \d :匹配一个数字字符
re_str=r'0\d\d' :匹配第一字符是0,后面两个字符都是任意数字的字符串
"""
re_str = r'\d\d'
print(re.fullmatch(re_str, '20'))
"""
*(5) \b :检测边界(单词边界--->一般符号都可以作为单词边界)
re_str=r'\b...\b' :匹配三个任意字符的前面和后面都是单词边界(空格、逗号、句号、问好、感叹号)的字符串
"""
re_str = r'...\b'
print(re.match(re_str, '1c_'))
"""
(6) ^ :检测字符串开始(查找时有用)
^The :检测以The开头的字符串
"""
re_str = r'^The'
print(re.fullmatch(re_str, 'The')) # <_sre.SRE_Match object; span=(0, 3), match='The'>
print(re.findall(r'^The', 'The221kjflksa')) # ['The']
"""
(7) $ :检测字符串结束
"""
re_str = r'123$$'
print(re.findall(re_str, 'ncosnkssn1234123')) # ['123']
"""
(8) \W :匹配非字母、数字、下划线
"""
re_str = r'\W\w'
print(re.fullmatch(re_str, '&_')) # <_sre.SRE_Match object; span=(0, 2), match='&_'>
"""
(9) \S :匹配非空白字符
"""
re_str = r'\s\S\d'
print(re.fullmatch(re_str, '\n%2')) # <_sre.SRE_Match object; span=(0, 3), match='\n%2'>
"""
(10) \D :匹配非数字字符
"""
re_str = r'\D\d\w'
print(re.fullmatch(re_str, 'a2_')) # <_sre.SRE_Match object; span=(0, 3), match='a2_'>
"""
(11) \B :检测非边界
"""
re_str = r'\Babc'
print(re.fullmatch(re_str, 'abcabc')) # None
re_str = r'abc\B'
print(re.fullmatch(re_str, 'abc')) # None
print(re.match(re_str, 'abc0')) # <_sre.SRE_Match object; span=(0, 3), match='abc'>
re_str = r'ab\Bc'
print(re.fullmatch(re_str, 'abc')) # <_sre.SRE_Match object; span=(0, 3), match='abc'>
*正则表达式符号组合
"""
(12) [] :匹配[]中出现的任意一个字符
re_str=r'[\d\w\s] : 匹配中括号中的一个数字、或者一个空白符、或者数字字母下划线 的一种就可以了
re_str=r'[\d_]abc' :匹配第一位是数字或者是下划线,后面是abc
"""
re_str=r'abc[1a]'
print(re.fullmatch(re_str,'abc1'))
"""
(13) [^] :匹配不在字符串中括号中出现的任意一个字符
[0-9] :匹配0,1,2,3,4,5,6,7,8,9中的任意一个字符
[1-5] :匹配1,2,3,4,5中的任意一个字符(*而不是匹配1,或者-,或者5*)
[a-z] :匹配任意一个小写字母
[A-Z] :匹配任意一个大写字母
[a-zA-Z] :匹配所有的字母
"""
re_str=r'abc[^\da]' #匹配前三位是abc,第四位不是数字,也不是字符a 的就可以
print(re.fullmatch(re_str,'abc*'))
**练习:写一个正则表达式,判断一个字符串是数字字符串(不能是空串)
re_str1=r'\d[0-9]*'
re_str2=r'\d\d*'
re_str3=r'[0-9][0-9]*'
print(re.fullmatch(re_str1,'0'))
**练习:写一个正则表达式,检测一个字符串是否是合格的标识符(字母数字下划线,数字不开头)
re_str=r'[a-zA-Z_]\w*'
print(re.fullmatch(re_str,'W1_sf'))
"""
(14) * :匹配0次 或者多次
re_str=r'
"""
re_str=r'\d*abc' #匹配一个字符串,前面是0个或者是多个数字字符,然后是abc
print(re.fullmatch(re_str,'abc'))
"""
(15) + :匹配一次 或者多次
"""
re_str=r'\d+\w*' #匹配一个字符串,开头出现一次或者多次的数字字符,然后再匹配0次或者多次字母数字下划线
print(re.fullmatch(re_str,'12d42asdd')) #<_sre.SRE_Match object; span=(0, 11), match='12d42asdd'>
"""
(16) ? :出现匹配0次 或者1次
"""
re_str=r'[a-z]?123' #123 a123 b123
print(re.fullmatch(re_str,'123'))
**练习:判断一个字符串是否是正整数数字字符串
# re_str=r'[+]?[^0]\d*' bug:'++1200'
re_str=r'[+]?[1-9]\d*'
print(re.fullmatch(re_str,'++1200'))
"""
(17) {N} :匹配N次
re_str=r'\d{5}abc' :匹配任意数字5个,后加abc
"""
re_str=r'[12ab]{3}abc'
print(re.fullmatch(re_str,'121abc'))
"""
(18) {N,} :匹配大于等于N次
"""
# 练习:前面至少三位的数字字符串,,后面随意
re_str=r'\d{3,}.*'
print(re.fullmatch(re_str,'192412dasj34'))
"""
(19) {M,N} :匹配至少M次,最多N次
"""
# 练习:密码要求,数字字母下划线组成,并且是8-16位
re_str=r'[\da-zA-Z]{8,16}'
print(re.fullmatch(re_str,'riu3ejj98oi'))
"""
(20) | :分之 或者
"""
re_str=r'\d{3}|[a-z]{3}' #匹配一个字符串,是三个数字字符,或者三个小写字母
print(re.fullmatch(re_str,'123'))
"""
(21) () :匹配的时候是分组,让括号中的正则条件变成一个整体
"""
re_str=r'(abc){3}' #匹配一个字符串,abc整体重复3次
print(re.fullmatch(re_str,'abcabcabc'))
"""
===========以下了解=============
#在能够匹配到的前提下尽可能少
(22) *? :重复任意次,尽可能少的匹配
(23) +? :重复1次或多次,尽可能少的重复
(24) ?? :重复0次或者1次,尽可能少的重复
(25) {N,}? :重复至少N次,尽可能少的重复
(26) {M,N}? :重复M到N次,尽可能少的重复
"""
re_str=r'a*?'
print(re.match(re_str,'aaaaaaa')) #''
符号 | 解释 | 示例 | 说明 |
---|---|---|---|
. | 匹配任意字符 | b.t | 可以匹配bat / but / b#t / b1t等 |
\w | 匹配字母/数字/下划线 | b\wt | 可以匹配bat / b1t / b_t等 但不能匹配b#t |
\s | 匹配空白字符(包括\r、\n、\t等) | love\syou | 可以匹配love you |
\d | 匹配数字 | \d\d | 可以匹配01 / 23 / 99等 |
\b | 匹配单词的边界 | \bThe\b | |
^ | 匹配字符串的开始 | ^The | 可以匹配The开头的字符串 |
$ | 匹配字符串的结束 | .exe$ | 可以匹配.exe结尾的字符串 |
\W | 匹配非字母/数字/下划线 | b\Wt | 可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等 |
\S | 匹配非空白字符 | love\Syou | 可以匹配love#you等 但不能匹配love you |
\D | 匹配非数字 | \d\D | 可以匹配9a / 3# / 0F等 |
\B | 匹配非单词边界 | \Bio\B | |
[] | 匹配来自字符集的任意单一字符 | [aeiou] | 可以匹配任一元音字母字符 |
[^] | 匹配不在字符集中的任意单一字符 | [^aeiou] | 可以匹配任一非元音字母字符 |
* | 匹配0次或多次 | \w* | |
+ | 匹配1次或多次 | \w+ | |
? | 匹配0次或1次 | \w? | |
{N} | 匹配N次 | \w{3} | |
{M,} | 匹配至少M次 | \w{3,} | |
{M,N} | 匹配至少M次至多N次 | \w{3,6} | |
| | 分支 | foo|bar | 可以匹配foo或者bar |
(?#) | 注释 | ||
(exp) | 匹配exp并捕获到自动命名的组中 | ||
(?<name>exp) | 匹配exp并捕获到名为name的组中 | ||
(?:exp) | 匹配exp但是不捕获匹配的文本 | ||
(?=exp) | 匹配exp前面的位置 | \b\w+(?=ing) | 可以匹配I'm dancing中的danc |
(?<=exp) | 匹配exp后面的位置 | (?<=\bdanc)\w+\b | 可以匹配I love dancing and reading中的第一个ing |
(?!exp) | 匹配后面不是exp的位置 | ||
(?<!exp) | 匹配前面不是exp的位置 | ||
*? | 重复任意次,但尽可能少重复 | a.*b a.*?b |
将正则表达式应用于aabab,前者会匹配整个字符串aabab,后者会匹配aab和ab两个字符串 |
+? | 重复1次或多次,但尽可能少重复 | ||
?? | 重复0次或1次,但尽可能少重复 | ||
{M,N}? | 重复M到N次,但尽可能少重复 | ||
{M,}? | 重复M次以上,但尽可能少重复 |
二、实例
正则中:
. \ [] {} () * + ? ^ $ |
这些字符有特殊意义,所以在正则表达式中,如果想要单纯的表达这些字符,需要在前面加\
注意:
(1)-
在中括号中可能是特殊的符号,也用\
(2). {} () * + ? $ |
在中括号中可以不用加,来表示字符
import re
if __name__ == '__main__':
re_str = r'\d+[1\-3]\d+'
print(re.fullmatch(re_str, '12-89'))
re_str = r'[\^]' # 匹配 字符^
re_str = r'[\\]' # 匹配 字符\
re_str = r'[\$]'
re_str = r'[{}]'
print(re.fullmatch(re_str, '{'))
# 1. \N --> 匹配前面第N个组中匹配到的内容
re_str = r'([1-9][a-z]{2})n(\d)\1\2'
print(re.fullmatch(re_str, '9hjn09hj0'))
练习:验证输入用户名和QQ号,是否有效。
用户名必须由字母数字下划线构成,且长度在6—20个字符之间
QQ号是5-12的数字且首位不为0
user_name=r'\w{6,20}'
QQ=r'[1-9]\d{4,11}'
练习:判断IP地址是否合法
分析:x.x.x.x
x: 1-255
写一个正则表达式判断一个字符串是否是:1-255
1-9
10-99
100-199
200-249
250-255
IP=r'(([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])'
print(re.fullmatch(IP,'1.13.189.205'))
三、re模块方法
import re
if __name__ == '__main__':
"""
1.compile(正则字符串):将正则表达式字符串转换成正则表达式对象,
转换成正则表达式之后,可以通过对对象调用相关的方法
"""
re_obct=re.compile(r'\w{6,12}')
print(re_obct.fullmatch('adafafdad')) # print(re_obct.fullmatch('adafafdad'))
print(re.fullmatch(re_obct,'adafafdad')) #<_sre.SRE_Match object; span=(0, 9), match='adafafdad'>
"""
2.fullmatch(正则表达式,字符串)--->完全匹配,从字符串开头匹配到结尾
返回值是匹配对象
应用:判断一个字符串是否符合某种字符串(判断账号、密码是否符合要求等)
"""
match=re.fullmatch('\w{3}','h_3')
print(match) #<_sre.SRE_Match object; span=(0, 3), match='h_3'>
# (1)获取匹配到的结果
print(match.group()) #h_3
# (2)获取匹配到的范围
print(match.span()) #(0, 3)
# (3)获取匹配到的开始下标和结束下标
print(match.start(),match.end()) #0 3
#(4)获取被匹配的字符串(原字符串),如果匹配失败返回None
print(match.string) #h_3
"""
3.match(正则表达式,字符串) 不完全匹配,从字符串开头开始匹配,匹配到正则表达式对应的范围为止
应用:判断一个字符串是否是以某种字符串开头
"""
match=re.match('\w{3}','ah2kdj')
print(match) #<_sre.SRE_Match object; span=(0, 3), match='ah2'>
print(match.group()) #ah2
print(match.string) #ah2kdj
"""
4.search(正则表达式,字符串) :在指定的字符串中**查找**某种字符串(以正则表达式来描述),
若有多个满足条件,只获取第一个,返回值是匹配对象,若找不到则返回None
应用:判断一个字符串中是否包含某种字符串
"""
print(re.search(r'\d{2,}[a-z]','adk233a234k')) #<_sre.SRE_Match object; span=(5, 9), match='233a'>
"""
5.findall(正则表达式,字符串):去获取指定字符串中满足正则条件的所有子串
返回值是列表,列表中是符合要求的字符串 ,没有满足要求的子串,就返回[]
"""
result=re.findall(r'\D\d+\D','aj131sshk*123_ad')
print(result) #['j131s', '*123_']
result=re.findall(r'[a-zA-Z](\d+)','12ada42%321k2')
print(result) #['42', '2']
**注意:在通过正则表达式获取子串的时候,可以通过在正则表达式中添加括号,来约束获取的内容(只捕获括号中匹配到的内容),匹配的时候,还是按原正则表达式去查找
应用:提取满足字符串的条件**
"""
6.finditer(正则表达式,字符串) :用法和findall一样,只是返回值的类型不一样
返回一个迭代器
注意:()捕获部分无效
"""
result=re.finditer(r'[a-zA-Z](\d+)','12ada42%321k2')
for match in result:
print(match)
'''
结果:
< _sre.SRE_Match object; span = (4, 7), match = 'a42' >
< _sre.SRE_Match object; span = (11, 13), match = 'k2' >
'''
"""
7.split(正则表达式,字符串) :按正则表达式匹配到的字符串进行切割
返回值是列表,列表元素就切割后被分段的字符串
"""
#字符串切法:
print('sjk2567sj890cvmsjfgbxusj'.split('sj')) # ['', 'k2567', '890cvm', 'fgbxu', '']
result=re.split(r'\d+','2a*sf5ad7%*8af8hgd9')
print(result) #['', 'a*sf', 'ad', '%*', 'af', 'hgd', '']
"""
8.sub(正则表达式,新字符,原字符串):在原字符串中查找符合正则的子串,替换成新的字符串
返回值是替换后的字符串
"""
#将指定字符串中所有的'sb' 替换成'*'
str1='sb,全都是sb'
result=re.sub(r'sb|傻|艹','*',str1)
print(str1,result) #sb,全都是sb *,全都是*
例子:替换字符串中的不良内容
import re
def main():
sentence = '你丫是傻叉吗? 我操你大爷的. Fuck you.'
purified = re.sub('[操肏艹草曹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞笔',
'*', sentence, flags=re.IGNORECASE)
print(purified) # 你丫是*吗? 我*你大爷的. * you.
函数 | 说明 |
---|---|
compile(pattern, flags=0) | 编译正则表达式返回正则表达式对象 |
match(pattern, string, flags=0) | 用正则表达式匹配字符串 成功返回匹配对象 否则返回None |
search(pattern, string, flags=0) | 搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None |
split(pattern, string, maxsplit=0, flags=0) | 用正则表达式指定的模式分隔符拆分字符串 返回列表 |
sub(pattern, repl, string, count=0, flags=0) | 用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数 |
fullmatch(pattern, string, flags=0) | match函数的完全匹配(从字符串开头到结尾)版本 |
findall(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回字符串的列表 |
finditer(pattern, string, flags=0) | 查找字符串所有与正则表达式匹配的模式 返回一个迭代器 |
purge() | 清除隐式编译的正则表达式的缓存 |
re.I / re.IGNORECASE | 忽略大小写匹配标记 |
re.M / re.MULTILINE | 多行匹配标记 |
网友评论