一、正则表达式
正则表达式由普通字符和元字符组成,普通字符包含大小写字母,数字。在匹配普通字符的时候直接些就可以了。
元字符:元字符才是正则表达式的灵魂。
1、字符组
用方括号[]中括起来,在[]中出现的内容会被匹配
如果字符组中的内容过多还可以使用-,[a-z][0-9][A-Z][A-Za-z0-9]
2、简单元字符
基本的元字符
. 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾 ^ 匹配字符串的开始 $ 匹配字符串的结尾 \W 匹配非字母和数字或下划线 \D 匹配非数字 \S 匹配非空白符 a|b 匹配字符a或字符b () 匹配括号内的表达式,也表示一个组 [...] 匹配字符组中的字符 [^...] 匹配出了字符组中字符的所有字符
3、量词
匹配多个字符
* 重复0次或更多次 + 重复一次或更多次 {n} 重复n次 {n,} 重复n次或更多次 {m,n} 重复n到m次
4、惰性匹配和贪婪匹配
在量词中的* ,+,{}都属于贪婪匹配,就是尽可能多的匹配到结果
str:周游昨天去大连玩耍了 reg:周游.* 此时匹配的是整句话
在使用 .* 后面如果加了?则是尽可能的少匹配,表示惰性匹配
str:周游昨天去大连玩耍了 reg:周游.*? 此时匹配的是 :周游
.*?x 的特殊含义找到下一个x为止
str:abcdefghixjklmnopq reg: .*?x 结果:abcdefghi
5、分组
在正则中使用()进行分组,比如匹配一个身份证号,老的身份证号由15位,新的有18位,而且有可能以X结尾
身份证号 ^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ 邮箱 \w+@[0-9a-zA-Z]+\.[a-zA-Z]+ 手机号 0?(13|14|15|17|18|19|16)[0-9]{9} 匹配生日 \d{4}(\-|\/|.)(([0][1-9])|([1][0-2]))\1(([0][1-9])|([1-2][0-9])|([3][0-1]))
6、转义
在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是“换行符”就需要对“\”进行转义,变成“\\”,在python中,无论是正则表达式,还是待匹配的内容,都是以字符的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次“\n”,字符串中要写成“\\n”,那么正则里就要写成“\\\\n”,这样比较麻烦,这时就需要用r'\n'这个该奶奶,此时的正则就是r'\\n'.
二、re模块
re模块是python提供的一套关于处理正则表达式的模块,核心功能
(?P<name>正则)
1、search会进行匹配,但是如果匹配到了第一个结果,就会返回结果;如果匹配不上search则返回None
# search 搜索,查找 # 一旦匹配到结果,直接返回,如果匹配不到结果,返回None。 import re result = re.search('\d','你的电话是什么182999999') print(result) print(result.group()) 结果: <_sre.SRE_Match object; span=(7, 8), match='1'> 1
2、match 只能从字符串的开头进行匹配
# 匹配,从头开始匹配,相当于你的正则前面加了一个^ result = re.match("\d+","1188我的电话是188897888") print(result) print(result.group()) 结果: <_sre.SRE_Match object; span=(0, 4), match='1188'> 1188
search和match的区别:search查找,找到结果就返回,match从头开始匹配
3、findall 查找所有,返回list
result = re.findall('\d+','baby的电话是1234565') print(result) 结果: ['1234565']
4、finditer 和findall差不多,但是finditer返回的是迭代器
result = re.finditer('\d+','周周的电话时1435634') for el in result: print(el.group()) 结果: 1435634
5、group("name") 获取数据
# 坑:爬虫的坑 # .*? result = re.finditer(r"姓名:(?P<name>.*?),爱好:(?P<hobby>.*?),","姓名:周周,爱好:跳舞,") for el in result: print(el.group("name"),el.group("hobby"))
6、compile() 编译
code = 'for i in range(10):print(i)' c = compile(code,"","exec") # 编译 exec(c) # 快速执行
reg = re.compile(r"\d+") # 编译了一段正则,加载了一段正则 lst = reg.findall('明天,你要去12306吗,还是去10086') print(lst) 结果: ['12306', '10086']
7、 re.S 去掉 . 的换行
在网也源码中会有空白,加re.S可去掉这些空白
8、split 切割
# 正则的常用操作 s = re.split("\d+","今天是29号,回头2号了就上课了") print(s) 结果: ['今天是', '号,回头', '号了就上课了']
9、sub 替换目标字符串
# 用正则替代 s = re.sub("\d+","__ps__","今天是29号,回头2号了就上课了") print(s) 结果: 今天是__ps__号,回头__ps__号了就上课了
10、subs 替换目标字符串并返回元组,并对替换的次数计数
s = re.subn("\d+","__ps__","今天是29号,回头2号了就上课了") print(s) 结果: ('今天是__ps__号,回头__ps__号了就上课了', 2)
11、(?:) 把表达式从python中的正则分组变成了原来正则表达式中的分组
lst = re.findall(r"a(?:\d+)c", "a3456c") # 把括号python中的分组变成了原来正则表达式中的分组 print(lst) lst = re.findall(r"a(\d+)c", "a3456c") print(lst) 结果: ['a3456c'] ['3456']