正则表达式(或 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 re2 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表中是有意义的,所以前面要加个r8 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\d{3})/(?P \w{3})','weeew34ttt123/ooo') 5 print(res.group()) # 123/ooo 6 print(res.group('id')) # 123 7 print(res.group('name')) # ooo 8 9 # findall10 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 # search16 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())# sb18 19 # match:同search,不过尽在字符串开始处进行匹配20 res = re.match('sb','sbaee')21 print(res) # <_sre.SRE_Match object; span=(0,2), match='sb'>,没匹配到则返回None22 print(res.group())# sb23 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..bbb35 res = re.sub('ab','123','ablexbab',1) # 最后一个参数是替换几次36 print(res) # 123lexbab37 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) #54 for i in res:55 print(i.group())56 # 157 # 258 # 359 # 460 # 5