python常用模块与正则表达式
一,正则表达式
1,在线测试工具:http://tool.chinaz.com/regex/
字符组:在正则表达式中用[ ]表示,在python中是列表
简单的正则表达式[ ]中数字是0-9,a-z,A-Z匹配时只能匹配一个数字,正则单纯的只认识数字,字母,字符等,没有复数,小数乱七八糟,以数字为例简写时只能是0-9,不能是9-0
表示数字的字符组:[13466872],[0123456789],简写[0-9],[2-8]
****[0-9a-zA-Z]除其他,只包含数字,字母范围,一次只能匹配一个。
简单例子:
[0123456789]------8----------True 字符组0-9,要匹配的数8,匹配结果True,超出字符组如a则不能匹配
[0-9]---------7---------True 和上例一样意思,不同表示而已
[a-z] ---------s-------True 用于匹配所有的小写字母
[A-Z]----------B--------True 用于匹配所有的大写字母
[0-9a-zA-Z]--------8,a,S-------True 均可匹配,每次只匹配一个(记得遵循范围)
2,字符:
元字符与匹配内容
.(点) -----------匹配除换行符以外的任意字符
\w -----------匹配字母或数字或下划线
\s -----------匹配任意的空白符,空格
\d -----------匹配任意数字
\W ----------匹配非字母或数字,下划线(一般是符号)
\D ----------匹配非数字
\S ---------匹配非空白符
\n -----------匹配一个换行符
\t -----------匹配一个制表符(tab)
\b ----------匹配一个单词的结尾(单词以什么结尾即可匹配)
^ -----------匹配字符串的开始(以什么开头可匹配)放在开头
$ -----------匹配字符串的结尾(字符串以什么结尾),跟在字符串的后面
******(\b与$区别) \b在匹配结尾时前面必须的加r,$不用就能匹配。如果在一个字符串或单词中有多个相同的匹配项且中间以空格分隔单词,\b都会匹配,$只会匹配最后一个。
a | b -----------匹配字符a或字符b
() -----------匹配括号内的表达式
[.......] ----------匹配字符组中的字符
[^.....] ----------匹配除了字符组中字符的所有字符
3,量词
* ----------重复零次或更多次
+ ----------重复一次或更多次
? ----------重复一次或零次
{n} ---------重复n次
{n,} ----------重复n次或更多次
{n,m} ----------重复n到m次
4, . ^ $例子
海 . ------------海东,海燕,海椒,海依依 -----------匹配有海字且海字后紧跟的一个字符,别的都不匹配
^哈 -----------只从开头开始匹配第一个哈字,多余的字符都不匹配
五$ ------------只匹配结尾五字,只匹配一个,除五之外别的都不匹配
5,贪婪匹配符 * + ? 尽可能多的匹配
正则 待匹配字符串 匹配结果 说明
李.? ------------李杰李莲英和李二棍子 -----------李杰,李莲,李二 ------------?表示重复0次或一次只匹配包含李字只取李字后的一个任意字符
李.* ------------李杰李莲英和李二棍子 ------------李杰李莲英和李二棍子----------*表示重复0次或多次,即匹配(包含李)李后面的0个或任意多个字符(贪婪匹配)
李.+ -----------李杰李莲英和李二棍子 ------------李杰李莲英和李二棍子----------+表示重复一次或多次,即匹配(包含李)李后面的1个或任意多个字符(贪婪匹配)
李.{1,2}-----------李杰李莲英和李二棍子------------李杰李李二棍-----------{1,2}匹配1到2次任意字符(包含李)
*****注意:*?组合将变成惰性匹配
李.*? ------------李杰李莲英李二棍子----------李李李 ------------惰性匹配
6,字符集 [ ] [^]
正则 待匹配字符 匹配结果 说明
李[杰光狗] 李杰和李光年和李狗 李杰,李光,李狗 正则和待匹配字符对应匹配任意次
李[^和]* 李杰和李莲英和李二棍子 李杰,李莲英,李二棍子 匹配一个不是‘和’的字符任意次
[\d] 456abc3 4,5,6,3 匹配单一的一个数字
[\d]+ 456abc123 456,123 匹配任意个数字(连在一起的拼接在一起)
7,分组()与或 | [^]
正则 待匹配字符 匹配结果 说明
^[1-9]\d{13,16}[0-9x]$ 110101198001017032 110101198001017032 匹配一个正确身份证号
8,转义符 \
元字符:\d ,\s
正则 待匹配字符 匹配结果 说明
\d \d False 特殊字符,不能匹配本身
\\d \d True 转移\之后变成\\,即可匹配
‘\\\\d’ '\\d' True python中字符串中‘\’ 转义每个字符串‘\’需转义
r‘\\d’ r'\d' True 在字符串之前加r,整个字符串不转义
9,贪婪匹配:满足匹配时,尽可能多的字符串,默认情况下采用贪婪匹配
正则 待匹配字符 匹配结果 说明
<.*> <script>.....<script> <script>.....<script> 默认贪婪匹配模式,尽可能匹配
<.*?> r'\d' <script>, <script> 加?贪婪匹配将变成惰性匹配
10,常见的费贪婪匹配
*? 重复任意次,但尽可能少重复 +? 重复1次或更多次,但尽可能少重复 ?? 重复0次或1次,但尽可能少重复 {n,m}? 重复n到m次,但尽可能少重复 {n,}? 重复n次以上,但尽可能少重复
11, . * ?的用法
. 是任意字符 * 是取 0 至 无限长度 ? 是非贪婪模式。 何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在: .*?x 就是取前面任意长度的字符,直到一个x出现
二,常用模块(python模块需要在import关键字导入下使用)
1,re模块
re模块下的常用方法
import re ret = re.findall('a','eva egon yuan') # print(ret) # 'a' 为正则, 'eva egon yuan'为待匹配字符串 # findall:匹配出字符串中所有的‘a’,返回字符组 ret1 = re.search('a','eva egon yuan') # print(ret1) #search 后同上,search查找,只找第一个匹配模式然后返回一个迭代器,用group()方法将迭代转为匹配结果, # 如果找不到匹配结果则返回None ret2 = re.match('a','ab egon ayuan').group() # print(ret2) #match后同上 match 匹配 同search 只匹配字符串开头,字符串的开头对应正则才能匹配,不然报错 #返回一个迭代器,要group方法取得匹配结果 # ret3 = re.split('ab','abcd') #这里ab是一个整体,整体分隔 ret3 = re.split('[a]','abcd') #先按a分隔,得到‘’,‘bcd’,再将'','bcd'整体按b分隔 # print(ret3) ret4 = re.sub('\d','H','eva3egon4yuan4',1) # print(ret4) #sub 替换 '\d' 数字 'H' 正则 'eva3egon4yuan4' 待匹配的字符串 1---替换次数 ret5 = re.subn('\d','H','eva3egon4yuan4') # print(ret5) #subn 全部替换 '\d'数字 'H'正则 'eva3egon4yuan4' 待匹配的字符串 #将字符串中的数字全部替换成‘H’,返回一个元祖,后跟替换次数 # boj = re.compile('\d{2}') #将正则表达式编译成为一个正则表达式对象 规定要匹配2个数字 # ret = boj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串 # print(ret.group()) #compile 编译正则 ‘\d’数字 {2} 匹配两个数字 import re ret6 = re.finditer('\d','ds3sy478a') #finditer返回存放结果的迭代器 # for i in ret6: # print(i.group()) #查看所有的数字 # print(ret6) # print(next(ret6).group()) #查看第一个数字 # print(next(ret6).group()) #查看第二个数字 # print([i.group() for i in ret6]) #查看剩余的数字结果 #1,findall的优先级查询 import re ret7 = re.findall('www.(baidu|oldboy).com','www.oldboy.com') # print(ret7) #这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可 # ret8 = re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') # print(ret8) #2,split的优先级查询 ret9 = re.split('\d+','eva3egn4yuan') # print(ret9) #以数字分隔 ret10 = re.split('(\d+)','eva3egon4yuan5fggfd') print(ret10) #给数字‘\d’加上括号是以数字分隔,但保留数字