2019-7-17 正则表达式和re模块
一、re模块与正则表达式之间的关系
正则表达式不是python独有的,它是一门独立的技术
所有的编程语言都可以使用正则
但是如果你想在python中使用,你就必须依赖于re模块
正则的官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定的字符、以及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来表达对字符串的一种过滤逻辑。
简单来说:正则就是用来筛选字符串中特定的内容。如果一个位置的值,不会出现变化,那么就不需要用到正则了,我们需要考虑的是在同一个位置上可能会出现的所有可能的字符。
二、正则表达式
1.字符组:[字符组]
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
字符分为很多类,比如数字、字母、标点等等
一个字符串里面的表达式都是或的关系 [0-9x]:表示的0-9的数字或者字母x
2.字符(元字符):元字符包括以下这些,把框起来的当一组记忆
元字符需要注意的几点:
1.^和$连用会精确限制匹配的内容,两者中间写什么,匹配的字符串就是什么,不能多一个也不能少一个
2.abc|ab 匹配时候字符串长的一定要先放在前面
3.^直接写在外面,是限制字符串的开头。$限制字符串的结尾
4.[^]表示除了[]里面的字符,其他的字符都要
5.分组()当多个正则符号需要多次重复的时候或者当做一个整体进行其他操作,那么可以以分组的形式
3.量词
量词需要注意的几点:
1.量词必须跟在正则符号的后面,量词只能够限制紧挨着它的那一个正则符号(记住是只能够限制紧挨着的)
1.#正则表达式 海.* #需要筛选的字符 海燕啊海娇海东 #结果 海燕啊海娇海东 (.代表除了换行符之外的所有字符,*是重复多次,所以把所有结果都取出来了,贪婪模式) 2.#正则表达式 海.*? #需要筛选的字符 海燕啊海娇海东 #结果 海 海 海 (只匹配出三个海字,*?表示查找0次,作用于紧挨着的. 所以这个. 就当没有匹配)
2.正则在匹配的时候默认是贪婪匹配(尽可能多的匹配),你可以在量词后面加一个?就可以变成非贪婪匹配
*?表示匹配0次,+?表示匹配1次,??表示匹配0次
例题:
. ^ $
* + ? {}
字符集 [] [^] ([^..]也算一个占位)
分组() 或 |
转义符 \
贪婪匹配和非贪婪匹配
三、re模块的用法
三个需要掌握的方法
re.findall (找出字符串中符合正则表达式全部内容,并且返回的是一个列表,列表中的元素就是正则匹配的结果)
import re ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里 print(ret) #没有找到返回空列表 #结果 ['a', 'a']
re.search (返回的是一个对象,必须要用group()调用才会返回结果,一个group()返回一个结果)
注意:search只会根据正则查找一次,查到了结果就会停止查找,如果当查找结果不存在的情况下调用group会直接报错
import re res = re.search('a','eva egon jason') print(res) # search不会给你直接返回匹配到的结果 而是给你返回一个对象,找不到返回None print(res.group()) # 必须调用group才能看到匹配到的结果 #结果 a 只会返回一个结果
re.match (match只会匹配字符串的开头部分,下面这个题是e开头,但是正则找的是a,返回一个None)
注意:match只会匹配开头部分,找到了就返回一个对象然后用group获取,如果没找到就返回一个None
import re res = re.match('a','eva egon jason') print(res) #None print(res.group()) #报错
其他方法
re.split (切割)
import re ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 print(ret) # ['', '', 'cd'] 返回的还是列表
re.sub (替换)
import re ret = re.sub('\d', 'H', 'eva3egon4yuan4',1) # 将数字替换成'H',参数1表示只替换1个 # sub('正则表达式','新的内容','待替换的字符串',n) """ 先按照正则表达式查找所有符合该表达式的内容 统一替换成'新的内容' 还可以通过n来控制替换的个数 """ print(ret) # evaHegon4yuan4
re.subn (也是替换,但是返回结果不一样)
import re ret = re.subn('\d', 'H', 'eva3egon4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次) ret1 = re.subn('\d', 'H', 'eva3egon4yuan4',1) # 将数字替换成'H',返回元组(替换的结果,替换了多少次) print(ret)
#('evaHegonHyuanH', 3) # 返回的是一个元组 元组的第二个元素代表的是替换的个数
re.compile (把一个正则表达式编译成一个正则表达式对象)
import re obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字 ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串 res1 = obj.findall('347982734729349827384') print(ret) #结果是一个对象 print(ret.group()) #结果 : 123 print(res1) #结果 : ['347', '982', '734', '729', '349', '827', '384']
re.finditer (返回一个迭代器,用next+group取值)
import re 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]) #查看剩余的左右结果
分组优先机制:()在python re 模块中的应用
import re res = re.search('^[1-9]\d{14}(\d{2}[0-9x])?$','110105199812067023') print(res.group()) print(res.group(1)) # 获取正则表达式括号阔起来分组的内容 获取第一个括号的结果 print(res.group(2)) #获取第二个括号的结果
# 而针对findall它没有group取值的方法,所以它默认就是分组优先获取的结果
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') # ?:取消分组优先
print(ret) # ['www.oldboy.com']
split中()的用法
ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']
ret1=re.split("(\d+)","eva3egon4yuan")
print(ret1) #结果 : ['eva', '3', 'egon', '4', 'yuan']
给正则表达式取别名 (?P)
import re res = re.search('^[1-9](?P<password>\d{14})(?P<username>\d{2}[0-9x])?$','110105199812067023') print(res.group('password')) #10105199812067 print(res.group('username')) #023