正则表达式 Regular Expression
正则表达式
1.引入案例
代码演示:
import re #regular Expession #需求:判断一个qq号是否是合法的 """ 分析: 1.全数字 2.第一位数字不能为0 3.位数:5~11 """ def checkQQ(str): #不管str是否合法,假设合法 result = True #寻找条件推翻假设 try: #判断是否是全数字 num = int(str) #判断位数 if len(str) >= 5 and len(str) <= 11: #判断开头是否为0 if str[0] == "0": result = False else: result = False except ValueError as e: result = False return result print(checkQQ("6725675785678657")) #使用正则表达式实现上面的需求 result = re.match(r"[1-9]\d{4,10}","6725675786574657") print(result)
2.概述
正则表达式【Regular Expression】,简写为regex,RE,使用单个字符串来描述一系列具有特殊格式的字符串
功能:
a.搜索
b.替换
c.匹配
使用情景:
爬虫
验证手机号,验证邮箱,密码【用户名】
3.使用规则
3.1匹配单个数字或者字符
代码演示:
import re """ ----------匹配单个字符与数字--------- . 匹配除换行符以外的任意字符 [0123456789] []是字符集合,表示匹配方括号中所包含的任意一个字符 [good] 匹配good中任意一个字符 [a-z] 匹配任意小写字母 [A-Z] 匹配任意大写字母 [0-9] 匹配任意数字,类似[0123456789] [0-9a-zA-Z] 匹配任意的数字和字母 [0-9a-zA-Z_] 匹配任意的数字、字母和下划线 [^good] 匹配除了good这几个字母以外的所有字符,中括号里的^称为脱字符,表示不匹配集合中的字符 [^0-9] 匹配所有的非数字字符 \d 匹配数字,效果同[0-9] \D 匹配非数字字符,效果同[^0-9] \w 匹配数字,字母和下划线,效果同[0-9a-zA-Z_] \W 匹配非数字,字母和下划线,效果同[^0-9a-zA-Z_] \s 匹配任意的空白符(空格,回车,换行,制表,换页),效果同[ \r\n\t\f] \S 匹配任意的非空白符,效果同[^ \f\n\r\t] """ #[] :只匹配其中的一位 # - :表示一个区间 #1. #1.1编译正则表达式返回对象 pattern = re.compile(r"[abcd]") #正则表达式 [a-d] #1.2使用正则表达式匹配字符串,成功返回对象,并携带匹配之后额结果,如果匹配失败则返回None ret = pattern.match("dhello") #需要被匹配的字符串 print(ret) print(ret.group()) #2. pattern = re.compile(r"[s-z]") ret = pattern.match("xhello") print(ret) print(ret.group()) #3 pattern = re.compile(r"[0-9]") ret = pattern.match("5hello") print(ret) print(ret.group()) #4 pattern = re.compile(r"[0-9a-zA-Z]") ret = pattern.match("8hello") print(ret) print(ret.group()) #5 ^:脱字符【】否定的含义 pattern = re.compile(r"[^0-9]") ret = pattern.match("chello") print(ret) print(ret.group()) #6 \d:只匹配数字,等同于[0-9] pattern = re.compile(r"\d") ret = pattern.match("4") print(ret) print(ret.group()) #7. \w pattern = re.compile(r"\w") ret = pattern.match("7") print(ret) print(ret.group()) #8 \s pattern = re.compile(r"\s") ret = pattern.match("\t") print(ret) print(ret.group()) #9. .:匹配不到换行符【\n】 pattern = re.compile(r".") ret = pattern.match("\r") print(ret) print(ret.group())
3.2匹配边界字符
代码演示:
import re """ --------------锚字符(边界字符)------------- ^ 行首匹配,和在[]里的^不是一个意思 startswith $ 行尾匹配 endswith \A 匹配字符串开始,它和^的区别是,\A只匹配整个字符串的开头,即使在re.M模式下也不会匹配它行的行首 \Z 匹配字符串结束,它和$的区别是,\Z只匹配整个字符串的结束,即使在re.M模式下也不会匹配它行的行尾 \b 匹配一个单词的边界,也就是值单词和空格间的位置 bounds \B 匹配非单词边界 """ #search() print(re.search(r"^to","today is a good day")) print(re.search(r"day$","today is a good day")) #findall() #re.M print(re.findall(r"\Ato","today is a good day\ntoday is a good day",re.M)) print(re.findall(r"^to","today is a good day\ntoday is a good day",re.M)) #总结:\A只匹配第一行的行首,^匹配每一行的行首 #\b匹配边界【开始和结尾】,\B匹配的是非边界【中间】 print(re.search(r"er\b","never")) #er print(re.search(r"er\b","nerve")) #None print(re.search(r"er\B","never")) #None print(re.search(r"er\B","nerve")) #er
3.3匹配多个字符
代码演示:
import re """ -------------------匹配多个字符------------------------ 说明:下方的x、y、z均为假设的普通字符,n、m(非负整数),不是正则表达式的元字符 (xyz) 匹配小括号内的xyz(作为一个整体去匹配) x? 匹配0个或者1个x x* 匹配0个或者任意多个x(.* 表示匹配0个或者任意多个字符(换行符除外)) x+ 匹配至少一个x x{n} 匹配确定的n个x(n是一个非负整数) x{n,} 匹配至少n个x x{n,m} 匹配至少n个最多m个x。注意:n <= m x|y |表示或,匹配的是x或y """ #()当做一个整体去匹配,返回的结果为一个列表 print(re.findall(r"(ab)","aaacccaabbbbb")) print(re.findall(r"a?","aaacccaabbbbb")) print(re.findall(r"a*","aaacccaabbbbb")) print(re.findall(r"a+","aaacccaabbbbb")) """ ['a', 'a', 'a', '', '', '', 'a', 'a', '', '', '', '', '', ''] ['aaa', '', '', '', 'aa', '', '', '', '', '', ''] ['aaa', 'aa'] """ #恰好出现n次 print(re.findall(r"a{2}","aaacccaabbbbb")) #至少出现n次 print(re.findall(r"a{2,}","aaacccaabbbbb")) #{m,n}:至少出现m次,至多出现n次 print(re.findall(r"a{2,5}","aaacccaabbbbb")) #表示或 print(re.findall(r"a|b","aaacccaabbbbb")) #[ab]
3.4匹配分组
代码演示:
import re #匹配分组 #| :或 #() :整体 #search:会在字符串中从左向左进行查找,如果找到第一个符合条件的,则停止查找 #正则1|正则2:只要正则1或者正则2中的一个满足,则直接按照这个条件查找 pattern = re.compile("\d+|[a-z]+") ret = pattern.search("123-d223344aa$$aa") #abc123-d223344aa$$aa print(ret.group()) pattern = re.compile("([a-z]\d)+\w+") ret = pattern.search("abc123-d223344aa$$aa") #abc123-d223344aa$$aa print(ret.group())
3.5子模式
代码演示:
import re #子模式 #() #如果在正则表达式中出现\1 \2等标识符的时候,那么\1代表从左向右的第一个()中的内容。。。被称为子模式【简化正则表达式】 pattern = re.compile(r"<([a-z]+)><(\w+)>\w+</\2></\1>") ret = pattern.search("<div><span>hello</span></div>") print(ret.group()) #子模式访问 print(ret.group(1)) print(ret.group(2))
3.6贪婪和非贪婪
代码演示:
import re #贪婪和非贪婪【匹配一位还是匹配多位的区别】 #+ * :多次匹配【贪婪匹配】 #在+或者*后面添加?则改为非贪婪匹配 result1 = re.findall(r"a(\d+)","a23333333b") print(result1) #['23333333'] result1 = re.findall(r"a(\d+?)","a23333333b") print(result1) #['2'] #特殊情况;如果一个正则表达式的前后都有限定条件的时候,那么则不存在贪婪模式,?将不起作用 result1 = re.findall(r"a(\d+)b","a23333333b") print(result1) result1 = re.findall(r"a(\d+?)b","a23333333b") print(result1)
3.7模式修正
代码演示:
import re #模式修正 """ re.I:忽略大小写模式【ignorecase】 re.M:视为多行模式【more】 re.S:视为单行模式【single】 """ pattern = re.compile(r"^love",re.M) string = """ alove you love her love he """ result1 = pattern.search(string) print(result1.group()) pattern = re.compile(r"[a-z]+",re.I) result1 = pattern.search("LLLLLLlove") print(result1.group())
4.re模块中常用功能函数
代码演示:
import re #re模块中常用的函数 #1.compile() str1 = "today is a good day" str2 = r"\w*" pattern1 = re.compile(str2) print(pattern1.findall(str1)) #2.match() result = re.match(r"[1-9]\d{4,10}","6725675786574657") print(result) #3.search() #注意:只要匹配到一个符合条件的子字符串,则直接返回,后面的内容不参与搜索 print(re.search(r"\dcom","www.4comnghughs").group()) #4.findall() #注意;返回的结果为列表 #finditer(): 返回的结果为可迭代器 iter = re.finditer(r"\d+","12 fjhaehgj 66 fhaj ") print(iter) for i in iter: print(i) #获取值 print(i.group()) #获取下标 print(i.span()) #5.split() :返回一个列表 s1 = "1one2two3445545three454four56977878five" print(re.split(r"\d+",s1)) print(re.split(r"[0-9]{1,}",s1)) print(re.split(r"[^a-z]+",s1)) s2 = "zhangsan lilei lisi Han Jack" print(re.split(r" +",s2)) s3 = "zhangsan@@@@lilei##########lisi%%%Han&&&&&&&&&&&&&Jack" print(re.split(r"[^a-zA-Z]+",s3)) #6.sub() 替换,返回的是替换之后的字符串 string1 = "today is a good day today is a good da" #用-将空格替换 #参数:旧的字符换【正则表达式】 新的字符串 原字符串 print(re.sub(r"\s","-",string1)) #subn() 替换,返回一个元组(新的字符串,替换的次数) print(re.subn(r"\s","-",string1))