正则表达式和re模块
-
-
什么是正则表达式
-
一套匹配字符串的规则;
-
-
能做什么
-
检测输入字符串的合法性
-
从一个大文件中找到符合规则的所有内容
-
-
-
字符组
-
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
-
[abc]可以匹配a、b、c
-
字符组的的范围是根据ascii进行匹配的
-
[0-9] 数字
-
[a-zA-Z] 大小写
-
[0-9a-fA-F] 可以匹配数字,大小写形式的a~f,用来验证十六进制字符
-
正则待匹配字符匹配结果说明[0123456789]8True在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配[0123456789]aFalse由于字符组中没有"a"字符,所以不能匹配[0-9]7True也可以用-表示范围,[0-9]就和[0123456789]是一个意思[a-z]sTrue同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示[A-Z]BTrue[A-Z]就表示所有的大写字母[0-9a-fA-F]eTrue可以匹配数字,大小写形式的a~f,用来验证十六进制字符 -
-
元字符
正则表达式中能够帮助我们表示匹配内容的符号
元字符匹配内容. 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾 ^ 匹配字符串的开始 $ 匹配字符串的结尾 \W 匹配非字母或数字或下划线\D 匹配非数字\S 匹配非空白符a|b 匹配字符a或字符b() 匹配括号内的表达式,也表示一个组[...] 匹配字符组中的字符[^...] 匹配除了字符组中字符的所有字符[\d\D] 、 [\w\W] 、 [\s\S] 都可以表示匹配所有
-
量词
量词用法说明* 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 \d+(\.\d+) 整数或小数
-
贪婪匹配和非贪婪匹配
婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
正则 待匹配字符 匹配结果 说明 <.*> <script>...<script> <script>...<script> 默认为贪婪匹配模式,会匹配尽量长的字符串<.*?> <script>...<script> <script> <script> 加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串量词后面加上?,将贪婪匹配转化成非贪婪匹配
-
转义符
-
原本有特殊意义的字符,到了表达它本身意义的时候需要转义
-
有一些特殊意义的内容,放在字符组中会取消其特殊意义 [().*+?]
-
-在字符组中表示范围,取消该功能需要转义 [a\-z] 或者放在字符组最前面、最后面
在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对""进行转义,变成'\'。
在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成'\n',那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r'\n'这个概念,此时的正则是r'\n'就可以了。
正则 待匹配字符 匹配 结果 说明 \n \n False 因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配\n \n True 转义\之后变成\\,即可匹配"\\n" '\n' True 如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次r'\n' r'\n' True 在字符串之前加r,让整个字符串不转义 -
-
re模块
import re
#findall
ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']
#findall 优先级
ret = re.findall('www.(baidu|wen).com', 'www.wen.com')
print(ret) # ['wen'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ret = re.findall('www.(?:baidu|wen).com', 'www.wen.com')
print(ret) # ['www.wen.com']
#search
ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
#split 分割
ret=re.split('\d+','ase123we'r)
print(ret) #['ase','wer']
ret=re.split('(\d+)','ase123wer')
print(ret) #['ase','123','wer']
ret=re.split('\d(\d)\d','ase123wer')
print(ret) #['ase','2','wer']
#sub subn替换
ret=re.sub('\d+','H','aqz123qwe234',1) #可以指定替换的次数
print(ret) #'aqzHqwe234'
ret=re.subn('\d+','H','aqz123qwe234')
print(ret) #(aqzHqweH,2) 返回元组包括替换后的字符串和替换的次数
#match 匹配头,同search,不过尽在字符串开始处进行匹配
ret = re.match('a', 'abc').group() # 同search,不过尽在字符串开始处进行匹配
print(ret) #'a'
#compile 将正则表达式编译成一个对象,多次使用时可以节省时间
obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
ret1 = obj.findall('wee234tty345')
print(ret.group()) #结果 : 123
print(ret1) #[234,345]
#finditer 返回迭代器,节省空间
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器
print(ret) # <callable_iterator object at 0x10195f940>
print(next(ret).group()) #查看第一个结果
print(next(ret).group()) #查看第二个结果
print([i.group() for i in ret]) #查看剩余的结果
-
import re
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
#还可以在分组中利用?<name>的形式给分组起名字
#获取的匹配结果可以直接用group('名字')拿到对应的值
print(ret.group('tag_name')) #结果 :h1
print(ret.group()) #结果 :<h1>hello</h1>
ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
#如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
#获取的匹配结果可以直接用group(序号)拿到对应的值
print(ret.group(1))
print(ret.group()) #结果 :<h1>hello</h1>
#分组命名的引用
exp = '<abc>asrtyj58*(&*)</abc>dgyiad</qwe>'
ret=re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',exp)
print(ret) #'<abc>asrtyj58*(&*)</abc>' -

浙公网安备 33010602011771号