正则表达式(或 RE)是一种小型的、高度专业化的编程语言,它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
一、普通字符
二、元字符
1、元字符之. ^ $ * + ? { }
1 # 引入正则:进入模糊匹配 2 import re 3 4 # '.' 默认匹配除\n(换行符)之外的任意一个字符,若指定flags=re.DOTALL,则匹配任意字符,包括换行 5 res = re.findall('W..l','Hello World!!') # ['Worl'] 6 ret = re.findall('W..l','Hello W\nrld!!',flags=re.DOTALL) # ['W\nrl'] 7 8 # '^' 匹配字符开头,若指定flags=re.MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) 9 res = re.findall('^h...o','hjaookhello') # ['hjaoo'] 10 ret = re.findall(r'^a','\nabc\neee',flags=re.MULTILINE) # ['a'] 11 12 # '$' 匹配字符结尾,若指定flags=re.MULTILINE,这种也可以匹配上("foo$","bfoo\nsdfsf",flags=re.MULTILINE) 13 res = re.findall('a..x$','aaaalexauex') # ['auex'] 14 ret = re.findall('foo$','bfoo\nsdfsf',flags=re.MULTILINE) # ['foo'] 15 16 # '*' 匹配*号前的字符0次或多次 17 res = re.findall("ab*","cabb3abcbbac") # ['abb','ab','a'] 18 19 # '+' 匹配前一个字符1次或多次 20 res = re.findall("ab+","cabb3abcbbac") # ['abb','ab'] 21 22 # '?' 匹配前一个字符1次或0次 23 res = re.findall("ab?","cabb3abcbbac") # ['ab','ab','a'] 24 25 # '{m}' 匹配前一个字符m次,{m,n}则代表匹配次数的范围 26 res = re.findall("a{1,3}b","caaabb3abcbbaabc") # ['aaab','ab','aab'] 27 res = re.findall("a{1,3}b","aaaab") # ['aaab'] 28 29 #结论:*等于{0,+∞},+等于{0,+∞},?等于{0,1},推荐使用*、+、?
注意:前面的'*'和'+'都是贪婪匹配(尽可能的多匹配),后面加'?'使其成为惰性匹配(尽可能的少匹配)
1 import re 2 res = re.findall("ab+","abbbbb") # ['abbbbb'] 3 res = re.findall("ab*","abbbbb") # ['abbbbb'] 4 res = re.findall("ab+?","abbbbb") # ['ab'] 5 res = re.findall("ab*?","abbbbb") # ['a']
2、元字符之字符集[]
1 # []中有多个字符代表是或的关系 2 res = re.findall('c[on]m','comaxcnm') # ['com','cnm'] 3 res = re.findall('[a-z]','comaxcn') # ['c','o','m','a','x','c','n'] 4 5 # 元字符放在[]里,取消元字符的特殊功能(\、^、-例外) 6 res = re.findall('[w*+,$]','co,ma+wc$n*') # [',','+','w','$','*'] 7 8 # ^放在[]里,意味着取反 9 res = re.findall('[^t]','atxmetu') # ['a','x','m','e','u'] 10 res = re.findall('[^tx]','atxmetu') # ['a','m','e','u'] 11 12 # -放在[]里,代表范围 13 res = re.findall('[1-9a-z]','13mawcCB') # ['1','3','m','a','w','c'] 14 res = re.findall('[1-9a-zA-Z]','13mawcCB') # ['1','3','m','a','w','c','C','B'] 15 16 # 反斜杠后面跟普通字符实现特殊功能 17 res = re.findall('[\w\d]','13mawcCB') # ['1','3','m','a','w','c','C','B']
3、元字符之转译字符 \
1 # \d 匹配任何十进制数字,相当于[0-9] 2 # \D 匹配任何非数字字符,相当于[^0-9] 3 # \s 匹配任何空白字符,相当于[ \t\n\r\f\v] 4 # \S 匹配任何非空白字符,相当于[^ \t\n\r\f\v] 5 # \w 匹配任何字母数字字符,相当于[a-zA-Z0-9] 6 # \W 匹配任何非字母数字字符,相当于[^a-zA-Z0-9] 7 # \b 匹配一个特殊字符的边界 8 9 # '\' 反斜杠后面跟普通字符实现特殊功能 10 print(re.findall('\d{5}','ae12345cw67890')) # ['12345','67890'] 11 print(re.findall('\sasd','fak asd')) # [' asd'] 12 print(re.findall('\w','fak asd')) # ['f','a','k','a','s','d'] 13 print(re.findall(r'I\b','I am a LI$T')) # ['I', 'I'] 14 15 # 反斜杠后面跟元字符去除特殊功能 16 print(re.findall('a\.','a.jk')) # ['a.'] 17 print(re.findall('a\+','a+jk')) # ['a+']
我们再来看一下反斜杠“\”的匹配,如下:
1 # 匹配反斜杠 \ 2 print(re.findall('c\l','abc\le')) # 报错 3 print(re.findall('c\\l','abc\le')) # 报错 4 print(re.findall('c\\\\l','abc\le')) # ['c\\l'] 5 print(re.findall(r'c\\l','abc\le')) # ['c\\l'] 6 7 # 因为\b在ASCII表中是有意义的,所以前面要加个r 8 print(re.findall('\bblow','blow')) # [],匹配不到 9 print(re.findall(r'\bblow','blow')) # ['blow']
4、元字符之分组 ()
1 # ()分组,括号里的字符作为一个整体 2 print(re.findall('(as)','jdkasas')) # ['as', 'as'] 3 4 res=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo') 5 print(res.group()) # 123/ooo 6 print(res.group('id')) # 123 7 print(res.group('name')) # ooo 8 9 # findall 10 res = re.findall('www.(\w+).com','www.baidu.com') 11 print(res) # ['baidu'],有分组只取出组当中的内容 12 ret = re.findall('www.(?:\w+).com','www.baidu.com') 13 print(ret) # ['www.baidu.com'],加上?:取消分组权限 14 15 # search 16 res = re.search('www.(\w+).com','www.baidu.com') 17 print(res.group()) # www.baidu.com,与findall不同
5、元字符之管道符 |
1 # | 匹配|左或|右的字符 2 print(re.findall('(ab)|\d','rabhdg8sd')) # ['ab', ''] 3 print(re.search('(ab)|\d','rabhdg8sd').group()) # ab
6、re模块下的常用方法
1 # 正则表达式的方法 2 # re.findall() # 所有的结果都返回到一个列表里 3 # re.search() # 返回匹配到的第一个对象(object),对象可以调用group方法来拿取返回结果 4 # re.match() # 只在字符串开始匹配,也只返回一个对象,对象可以调用group方法来拿取返回结果 5 # re.split() # 匹配到的字符当做列表分隔符 6 # re.sub() # 匹配字符并替换 7 # re.subn() # 效果和sub一样,但是同时还会返回替换了多少次 8 # re.compile() # 把匹配规则编译成一个对象供后面多次使用 9 # re.finditer() # 返回的是一个迭代器 10 11 # findall:所有的结果都返回到一个列表里 12 print(re.findall('\d','12345')) # ['1','2','3','4','5'] 13 14 # search:匹配出第一个满足条件的结果 15 res = re.search('sb','adssbeeesb') 16 print(res) # <_sre.SRE_Match object; span=(3,5), match='sb'> 17 print(res.group())# sb 18 19 # match:同search,不过尽在字符串开始处进行匹配 20 res = re.match('sb','sbaee') 21 print(res) # <_sre.SRE_Match object; span=(0,2), match='sb'>,没匹配到则返回None 22 print(res.group())# sb 23 24 # split:匹配到的字符当做列表分隔符 25 res = re.split('k','djksal') 26 print(res) # ['dj','sal'] 27 res = re.split('[j,s]','dsejksal') 28 print(res) # ['d','e','k','al'] 29 res = re.split('[j,s]','sejksal') 30 print(res) # ['','e','k','al'] 31 32 # sub:匹配字符并替换 33 res = re.sub('a..x','s..b','eealexbb') 34 print(res) # ees..bbb 35 res = re.sub('ab','123','ablexbab',1) # 最后一个参数是替换几次 36 print(res) # 123lexbab 37 38 # subn:效果和sub一样,返回的是一个元组,除了返回的结果,还有替换了多少次 39 res = re.subn('a..x','s..b','eealexbb') 40 print(res) # ('ees..bbb',1) 41 res = re.subn('ab','123','ablexbab') # 最后一个参数是替换几次 42 print(res) # ('123lexb123',2) 43 44 # compile:把匹配规则编译成一个对象供后面多次使用 45 obj = re.compile('\.com') # 把匹配规则编译成一个对象 46 res = obj.findall('fajs.comeee') 47 ret = obj.findall('aa.comss.com') 48 print(res) # ['.com'] 49 print(ret) # ['.com','.com'] 50 51 # finditer:返回的是一个迭代器 52 res = re.finditer('\d','12345') 53 print(res) # <callable_iterator object at 0x000001E98FE4D7B8> 54 for i in res: 55 print(i.group()) 56 # 1 57 # 2 58 # 3 59 # 4 60 # 5