一、匹配模式字符
常用模式字符包括:
- 不带
\
的模式字符
模式 | 描述 |
---|---|
^ | 匹配开头 |
$ | 匹配结尾 |
. | 匹配字符(正常情况不包括\n) |
* | 匹配字符0个或者多个 |
? | 非贪婪匹配,既尽可能少的匹配 |
+ | 匹配至少一个 |
| | 或者,如匹配png或者jpg结尾的图片: re.search('http://.{,100}(png|jpg)',imgstring) |
[] | 表示一组字符,如[abc],匹配a或者b或者c,如果[^abc],则是匹配不是abc的 |
{} | 限定匹配数量,如{2,4},表示最少2个,最多4个,忽略开头表示0,忽略结尾表示最多匹配 |
() | 分组 |
- 带
\
的特殊模式字符
\w | 小写w,匹配数字、字母、下划线 |
\W | 大写W,匹配非(数字、字母、下划线) |
\s | 小写s,匹配任意非空字符,[\t\n\r\f] |
\S | 大写S,匹配任意空字符 |
\d | 小写d,匹配数字,[0-9] |
\D | 大写D,匹配非数字[^0-9] |
\G | 匹配最后匹配完成的位置 |
\b | 小写b,匹配单词边界,比如匹配以es结尾的单词.'es\b' |
\B | 大写B,匹配非单词边界 |
\n,\t,\r,\f | 换行,制表,回车,换页 |
二、常用方法
-
re.match(pattren, string, flags)
只从开头开始匹配。如果开头不符合条件,则不符合import re string = '123456' re.match('\d23', string) # 123 re.match('\d45', string) # none
-
re.search(pattren, string, flags)
跟match的区别是他可以在开头也可以在中间匹配,都是匹配一次import re string = '123456' re.search('\d23', string) # 123 re.search('\d45', string) # 345
-
re.findall(pattren, string, flags)
匹配多次,返回列表,如果没有匹配成功,则返回空列表import re string = '1234512345' re.findall('\d23', string) # ['123','123']
-
re.split(pattren, string, maxsplit, flags)
正则切割,跟str.split的区别是他可以在需要匹配的地方用正则表达式import re string = '1234512345' re.split('\d3', string) # ['1','451','45']
-
re.sub(pattren, repl, string, count, flags)
正则替换,repl可以是字符串也可以是函数import re string = '1234512345' re.sub('\d3', 'aa', string) # 1aa451aa45 #repl为函数 """ 假如我有'123451a2345' 我只想要23前面的数字的话就替换成AA,23前面不是数字的则不替换 """ import re string = '123451a2345' re.sub('\d23', 'AA', string) #AA451a2345 他会把前面的\d也替换掉 def replReplace(matched): return matched.group().replace('23', 'AA') re.sub('\d23', replReplace, string) #1AA451a2345 符合要求
三、flags常用常量
-
re.I
全写re.IGNORECASE
,忽略大小写import re string = '123Aa123' re.search('aa', string) # None re.search('aa', string, re.I) # Aa
-
re.A
全写re.ASCII
,让\w、\b、\s、\d等特殊字符只匹配ASCII码,而不是匹配Unicodeimport re string = '我爱你520Love' re.search('\w+', string) # '我爱你520Love' re.search('\w+', string, re.A) # '520Love' 因为中文不在ASCII表
-
re.S
全写re.DOTALL
让.
匹配所有字符,包括\n
换行符import re string = '123.\n123' re.search('3.*?3', string) # None re.search('3.*?3', string, re.S) # '3.\n123'
-
re.M
全写re.MULTILINE
,多行模式,用^
可以匹配多行模式下的开头。默认只能匹配第一个开头import re string = '123\n123' re.findall('^\d2', string) # ['12'] re.findall('^\d2', string, re.M) # ['12', '12']
四、结合例子
1、比如匹配整个HTML页面的图片.
PS::需要注意的是 如果findall()
里面包含有() 他会为里面的()分组,如果我们不在最外边加括号的话,那么我们只能得到他里面() 给我们所分的组。那为什么match() search()
又不需要呢,是他们默认最外层有(括号)
# 页面源码是html
import re
imglist = re.findall('(http(s)?://.*?(png|jpg))', html) # 返回列表[('最外层括号内容','顺序括号内容1', '顺序括号内容2'), ]
# 例如
html = 'url(http://img.baidu.com/img/baike/logo-baike.jpg)sfseurl(https://img.baidu.com/img/baike/logo-baike.png)'
imglist1 = re.findall('https{0,1}://.*?\.(png|jpg)', html) # 不加括号,他只得到图片后缀 既 imglist1 = ['jpg', 'png']
imglist2 = re.findall('(https{0,1}://.*?\.(png|jpg))', html) # 加括号。imglist2 = [('http://img.baidu.com/img/baike/logo-baike.jpg', 'jpg'), ('https://img.baidu.com/img/baike/logo-baike.png', 'png')]
PS:正则还是要在实际情况中结合数据灵活运用。如有错误欢迎指出。谢谢