python 正则
1.re.match(pattern,string,flags=0)
args:
- pattern:匹配方式
- string:需要匹配的字符串
- flags:有多种格式,详情添加链接描述
import re
print(re.match('www','www.baidu.com'))
print(re.match('www','www.baidu.com').span())
- 匹配方式:是从目标字符串的第一个开始匹配,不在最前面,匹配不上。匹配的到将返回一个对象,否则返回None,其中的span为方法,返回匹配到的目标字符串的下标。
- ps:match并不是,不能使用,会报错
2.re.search(pattern, string, flags=0)
print(re.search(r'er','nerver'))
print(re.search(r'er\b','never'))
print(re.search(r'er\b','erverd'))
print(re.search(r'a\b','dbc dsa da'))
print(re.search(r'er\B','erver'))
- 匹配方式:和match不一样,是在目标字符串中能匹配到一个就可以,同时只匹配一个,能匹配上就返回,否则None
- ps:这里出现了一个正则表达式模式
- \b:匹配字符串的后边界,也只匹配后边界
- \B:除了后边界,目标字符串都匹配
3.re.findall(string[, pos[, endpos]])
这里实现起来会有点不准确,使用到了re.compile,这个后面讲
print(re.findall(r'sunck','sunck is a good sunck'))
print(re.findall(r'a?','asaa')) # 每次只匹配一个,有就a 没有就‘’
print(re.findall(r'a*','asaa')) # 每次尽可能匹配,没有就‘’
print(re.findall(r'a+','asaa')) # 只有存在的情况下 才会有 可以有多个
print(re.findall(r'a{3}','aaasaa'))
print(re.findall(r'((s|S)unck)','sunck--Sunck'))
print(re.findall(r'//*.*/*/',r'/* 1231231 asdasrasd */'))
- 匹配方式:匹配出目标字符串中,所有匹配上的字符串,以列表的形式返回。
- ps:正则表达式模式
- ?:匹配方式,匹配出0个或1个,非贪婪模式。每次只匹配一个,符合就为匹配字符串(a),不符合就为’’,并且不会将连续符合的选中(非贪婪)。例子中,为s的时候打印为’’,连续连个a的时候,列表中也是两个a
- *:匹配方式,匹配出0个或多个,贪婪模式,相对于?,可以匹配连续的如’aa’。
- +:匹配方式,匹配1个或多个,贪婪模式,相对于*,匹配不上的,不会使用’'作代替。
- 最后一个:目的是读出注释中的字符串,可能有点绕,弄清楚一点,*在正则中表示出space以外的全部字符串,这里不想使用它的表达式模式,而是单纯的作为一个字符。
/*
就是*
。理解了就明白了。
4.re.split(pattern, string[, maxsplit=0, flags=0])
print(re.split('\W+', 'runoob, runoob, runoob.'))
print(re.split('(\W+)', 'runoob, runoob, runoob.'))
print(re.split('\W+', ' runoob, runoob, runoob.', 1) )
print(re.split('\s+', ' runoob, runoob, runoob.') )
- split是将匹配到的切割掉将剩下的作为数组返回。如第一个
- 这里使用到了分组的概念
group()
,使用后,被切割的字段也保存下来放在数组里,这里不太明白了加了分组以后为什么不一样,后面深挖。 - 第三个中,加了一个maxsplit的参数,所以只切割一次,默认为0,不限次数
- re.split相对于str.split的优点在于,它不限长短,如4中,多个空格 [\t\n\r\f] ,全部被切割掉了
5.re.finditer(pattern, string, flags=0)
obj = re.finditer(r'good?','goodsunck is a good good man')
print(obj)
for item in obj:
print(item)
- 匹配方式和findall一样,只不过返回的东西不太一样,返回的是一个可迭代对象,使用for循环将它打印出来。
6.re.sub(pattern, repl, string, count=0, flags=0)
# 匹配#后面所有的字符,并换成空字符''
print(re.sub(r'#.*$', "", '2004-959-559 # 这是一个国外电话号码'))
# 删除处数字以外所有的字符
print(re.sub(r'\D', "", '2004-959-559 # 这是一个国外电话号码'))
- 用途:替换字符串中匹配上的部分字符,这里使用类似split。
7.re.subn(pattern, repl, string, count=0, flags=0)
# 匹配#后面所有的字符,并换成空字符''
print(re.subn(r'#.*$', "", '2004-959-559 # 这是一个国外电话号码'))
# 删除处数字以外所有的字符
print(re.subn(r'\D', "", '2004-959-559 # 这是一个国外电话号码'))
- 讲一下和re.sub的区别,返回的结果里多了一个数字,这个数字代表匹配上被修改的次数,相对来说,看的更清楚
8.re.compile(pattern[, flags])
import re
obj = re.compile('www')
print(obj.match('www.baidu.com'))
- 这一个函数相当于生成一个带有固定正则表达式的对象,然后这个对象去使用前面提到过的其他的正则方法。这里只使用了match,其他的也都可以使用
9.group
matchObj = re.match( r'(.*) are (.*?) .*', 'Cats are smarter than dogs', re.M|re.I)
print('group',matchObj.group()) # 相当于 group(0)
print('group1',matchObj.group(1))
print('group2',matchObj.group(2))
print('groups',matchObj.groups())
- 可以从可以提取子串的功能。
- group():或者说group(0),获取匹配到的整个字符串。
- group(1):获取第一个分组中的字符串,这里是Cats
- group(2):获取第二个分组中的字符串,这里是smarter
- groups():以元祖的形式,返回所有分组的字符串
几个练手的小任务
# 正则匹配qq,邮箱,用户名是否符合要求
import re
def checkQQ(string):
pat = r'^[1-9]\d{5,9}$'
print(re.search(pat,string))
checkQQ('23112541')
checkQQ('23112541')
checkQQ('231a12541')
checkQQ('231125412312')
def checkEmail(string):
pat = r'^[1-9a-zA-Z_]\w{5,12}@\w{2,4}.com$'
print(re.search(pat,string))
checkEmail('1175dasd761@qq.com')
def checkUser(string):
pat = r'^\w\w{5,11}$'
print(re.search(pat,string))
checkUser('padsaes')
- ps:不一定是最优解,只是作为一种想到的解决方法
正则表达式的模式有很多,模式这里简单提一下
- ^:字符串开头
- $:字符串末尾
- .:匹配任意字符串,通常.*
- re{ n,m}:代表某个模式下可选的长度,最少为n,最多为m。可以只有一个 n<=m
完结撒花