正则表达式:
它是字符串的一种匹配模式,用来处理字符串,可以极大地减轻处理一些复杂字符串的代码量
字符组:它是在同一位置可能出现的各种字符组成了一个字符组,用[]表示,但是它的结果只能是一个数字或者一个大写字母或小写字母等
下面测试以该网站为例http://tool.chinaz.com/regex/
#正则表达式 匹配字符串 匹配结果 #[0-9] 9 9 [0-9]的写法就相当于在用[0123456789] #[0123456789] 0 0 #[a-z] 1 None 这里只匹配小写字符a-z而不匹配数字 #[a-z] z z #[A-Z] A A 这里只匹配大写字符串 #[A-Z0-5a-c] A6b A、b 这里的数字范围只有到0-5所以没匹配到6
元字符:
1.'.' 匹配除换行符以外的任意字符
#正则表达式 匹配字符串 匹配结果 # . a a # . 1 1 # . & & # . 换行符 None
2.'\w' 匹配字母或下划线或数字--word
等价于[A-Z0-9a-z_]
#正则表达式 匹配字符串 匹配结果 # \w a a # \w 1 1 # \w & None # \w 换行符 None # \w _ _
3.'\s' 匹配任意的空白符--space
匹配字符串如果什么都不写也会匹配到一个结果,这里的空白符有空格、tab键、回车等空白字符
4.'\d' 匹配任意的数字--digit
等价于[0-9]
#正则表达式 匹配字符串 匹配结果 # \d a None # \d 1 1 # \d & None
5.'\W' 匹配非字母或数字下划线
和'\w'的结果相反,且空白字符也可以匹配,如果用[\w\W]就相当于全局匹配的效果;等价于[^A-Z0-9a-z_]
6.'\D' 匹配非字符
和'\d'的结果相反,且空白字符也可以匹配;等价于[^0-9]
7.'\S' 匹配非空白字符
和'\s'的结果相反,除了空白字符串其他都匹配
8.'\n' 匹配一个换行符
9.'\t' 匹配一个制表符(tab)
10.'\b' 匹配一个单词的结尾
#正则表达式 匹配字符串 匹配结果 # .\b abx x 匹配一个字符并返回它的末尾字符 # b\b abb b 匹配一个字符串如果它的结尾是b就返回 # b\b aaa None
11.'\f' 匹配一个换页符
12.'\r' 匹配一个回车符
13.'\v' 匹配一个垂直制表符
14.'\B' 匹配一个非单词边界
#正则表达式 匹配字符串 匹配结果 # v\B vers v # ve\B vers ve # s\B vers None
15.'\num' 匹配一个正整数
#正则表达式 匹配字符串 匹配结果 # (.)\1 1122 11、22 匹配连续相邻的两个字符
16.'^' 匹配字符串开始
相当于startswith()
#正则表达式 匹配字符串 匹配结果 # ^[A-Z] A456A A
17.'$' 匹配字符串结束
相当于endswith()
#正则表达式 匹配字符串 匹配结果 # [A-Z]$ ASD D
18.'a|b' 匹配字符串a或b
先看左边符不符合条件,若符合则优先匹配左边,否则匹配右边
#正则表达式 匹配字符串 匹配结果 # 123|5 789a12352 123、5 #(ab|c)[0-9] 5ac5ab6 c5、ab6
19.'()' 匹配括号内的表达式也表示一个组
如果要匹配左括号'('就要用'\('语法,右括号')'就要用'\)'
#正则表达式 匹配字符串 匹配结果 # ([a-z]) aswss a、s、w、s、s
20.'[...]' 匹配字符组的字符
21.‘[^...]’匹配除了字符组中字符的所有字符
#正则表达式 匹配字符串 匹配结果 # [^abc] erasdbc e、r、s、d
量词:
用于约束前一个正则匹配的规则,要放在规则的后面
1.'*' 重复零次或多次
0次就是不是正则表示里需要的元素也会算一次
#正则表达式 匹配字符串 匹配次数 # [a]* abaacaaa 6 # [a-z]* abc 2 # []* 1
2.'+' 重复一次或更多次
#正则表达式 匹配字符串 匹配次数 # [a]+ abaacaaa 3 # [a-z]+ abc 1 # []+ 0
3.'?' 重复零次或一次
#正则表达式 匹配字符串 匹配次数 # [a]? abaacaaa 9 # [a-z]? abc 4 # []? 1
4.'{n}' 重复n次
5.'{n,}' 重复n次或更多次
6.'{n,m}' 重复n次到m次
#正则表达式 匹配字符串 匹配次数 匹配结果 # [a]{2,5} aaaaaaaaaaaaa 3 aaaaa、aaaaa、aaa #[a]{2,5}? aaaaaaaaaaaaa 6 aa、aa、aa、aa、aa、aa ?放在最后的作用是取最小的次数
用法注意:
1..^$
#正则表达式 匹配字符串 匹配结果 # a. abacadaf ab、ac、ad、af 匹配以a为开头的字符串 # ^a. abacadaf ab 只匹配一个从字符串中以a开头的字符串 # a.$ abacadaf af 只匹配一个从字符串中以a结尾的字符串
2.*+?{ }
#正则表达式 匹配字符串 匹配结果 # 一.? 一二一二三一二三四 一二、一二、一二 匹配一后面的一个任意字符 # 一.* 一二一二三一二三四 一二一二三一二三四 匹配一后面的0或多个任意字符 # 一.+ 一二一二三一二三四 一二一二三一二三四 匹配一后面的1或多个任意字符 # 一.{2,4} 一二一二三一二三四 一二一二三、一二三四 匹配一后面2-4个字符 # 一.{2,4}? 一二一二三一二三四 一二一、一二三 匹配一后面2个字符
*+?的匹配规则都属于贪婪匹配,即尽可能多的匹配,而在规则的最后加?会变成惰性匹配,即尽可能少的匹配
3.字符集[ ][^]
#正则表达式 匹配字符串 匹配结果 # a[bcd]* ab|abc|abcd ab、abc、abcd # a[^|]* ab|abc|abcd ab、abc、abcd # [\d] 123a56bc 1、2、3、5、6 # [\d]+ 123a56bc 123、56
4.转义符\
#正则表达式 匹配字符串 匹配结果 # \n \n None # \\n \n \n 这里的第一个\充当转义的作用 # \\\\n \\n \\n 每需要转义一个\都要在前面写一个\ # r\\\\n r\n r\n 加r会让整个结果不转义
5.非贪婪匹配
#正则表达式 匹配字符串 匹配结果 # a[a-z]*? aaaaaaa a、a、a、a、a、a、a(7次) # a[a-z]+? aaaaaaa aa、aa、aa(3次) # a[a-z]?? aaaaaaa a、a、a、a、a、a、a(7次) #a[a-z]{2,4}? aaaaaaa aaa、aaa(2次) #a[a-z]{2,}? aaaaaaa aaa、aaa(2次)
'.*?x’的作用是直到找到x就停止
#正则表达式 匹配字符串 匹配结果 # .*?a 45bjswakaabaa 45bjswa、ka、a、ba、a
6.身份证号是一个长度为15或18的字符串,如果是15位则全部是数字组成,首位不能为0,如果18位,则前17位全是数字,末尾可能是x或数字
# 正则表达式 匹配字符串 匹配结果 #^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ 122345688989788 122345688989788 #^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ 12234568898978811x 12234568898978811x
re模块:
常用方法:
1.findall()
返回所有满足匹配条件的结果并放在一个列表中
import re ret = re.findall('[a-z0-9]','aAbBcC123&') print(ret) #['a', 'b', 'c', '1', '2', '3']
优先级:
这里的问号具有取消分组优先级的作用
import re ret = re.findall('www.(baidu|google).com', 'www.google.com') print(ret) #['google'] ret = re.findall('www.(?:baidu|google).com', 'www.google.com') print(ret) #['www.google.com']
2.search()
在字符串中从左到右找到一个符合匹配标准的就返回一个对象,如果ret没有匹配到就返回None
import re ret = re.search('[a]+','12aaa78a8aa') print(ret) #print(ret.group()) #aaa ret2 = re.search('[A-Z]+','12aaa78a8aa') print(ret2) #None print(ret2.group()) #AttributeError: 'NoneType' object has no attribute 'group'
增加一个判断,如果有匹配成功就返回匹配的字符串,没成功就不执行
import re ret = re.search('[a]+','12aaa78a8aa') if ret: print(ret.group()) #aaa
注意:
import re ret = re.search('^[0-9](\d{5})(\d{2})?$','11534512') print(ret.group()) #11534512 print(ret.group(1)) #15345 拿到每一个分组的数值 print(ret.group(2)) #12
3.match()
这个方法就是从开头开始匹配,如果正则规则能够匹配的上开头,那么就返回一个对象,结果中的内容要group()方法才能显示,如果没有匹配上就返回None,调用group()就会报错
import re ret = re.match('[0-9a-z]+','abc123A33a') print(ret) #if ret: print(ret.group()) #abc123
4.split()
先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割得到''和'cd',分割完的字符会消失
import re ret = re.split('[ab]','abcd') print(ret) #['', '', 'cd']
优先级:
import re ret1 = re.split('\d+','abc1abcsw22asww3312a') print(ret1) #['abc', 'abcsw', 'asww', 'a'] ret2 = re.split('(\d+)','abc1abcsw22asww3312a') print(ret2) #['abc', '1', 'abcsw', '22', 'asww', '3312', 'a'] 加上了括号之后能够保留匹配项,没加括号则不保留匹配项
5.sub()
将正则规则匹配到的英文小写字母替换成'&',后面的5表示只替换5次
import re ret = re.sub('[a-z]','&','eva3sdww4asd22H3',5) print(ret) #&&&3&&ww4asd22H3
6.subn()
和sub执行效果几乎相同,结果会返回替换后的字符串和替换次数
import re ret = re.subn('[a-z]','&','eva3sdww4asd22H3',5) print(ret) #('&&&3&&ww4asd22H3', 5)
7.compile()
当一个正则规则需要被反复的调用且它的正则表达式很长,它就需要用到compile()
import re obj = re.compile('\d{3,5}') #将正则表达式编译成一个正则表达式对象,规则要匹配3-5个数字 ret = obj.search('abc12gha12432j1222') print(ret.group()) #12432 ret = obj.search('easda22132aasdw22sdaw') print(ret.group()) #22132
8.finditer()
结果可以返回一个存放结果的迭代器
import re ret = re.finditer('[a-z]{2,3}','12abs23saw7a8sddw') print(ret) #print([i.group() for i in ret]) #['abs', 'saw', 'sdd']
9.分组命名
import re ret = re.search("<(?P\w+)>\w+(?P=tag_name)> ","page
") #在分组中利用?的形式给分组取名字 print(ret.group('tag_name')) #h1 print(ret.group()) #page
import re ret = re.search(r"<(\w+)>\w+\1>","page
") #在分组中不想写名字的话可以用\序号来找到对应的组,表示要找的内容和前面组内容一致 print(ret.group(1)) #h1 print(ret.group()) #page
10.flags参数
re.I(IGNORECASE):忽略大小写,括号内是完整的写法
re.M(MULTILINE):多行模式,改变^和$的行为
re.S(DOTALL):点可以匹配任意字符,包括换行符
re.L(LOCALE):做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用
re.U(UNICODE):使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flag
re.X(VERBOSE):冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释