一.常用正则表达式符号和语法:
'.' 匹配所有字符串,除\n以外
‘-’ 表示范围[0-9]
'*' 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
'+' 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+
'^' 匹配字符串开头
‘$’ 匹配字符串结尾 re
'\' 转义字符, 使后一个字符改变原来的意思,如果字符串中有字符*需要匹配,可以\*或者字符集[*] re.findall(r'3\*','3*ds')结['3*']
'*' 匹配前面的字符0次或多次 re.findall("ab*","cabc3abcbbac")结果:['ab', 'ab', 'a']
‘?’ 匹配前一个字符串0次或1次 re.findall('ab?','abcabcabcadf')结果['ab', 'ab', 'ab', 'a']
'{m}' 匹配前一个字符m次 re.findall('cb{1}','bchbchcbfbcbb')结果['cb', 'cb']
'{n,m}' 匹配前一个字符n到m次 re.findall('cb{2,3}','bchbchcbfbcbb')结果['cbb']
'\d' 匹配数字,等于[0-9] re.findall('\d','电话:10086')结果['1', '0', '0', '8', '6']
'\D' 匹配非数字,等于[^0-9] re.findall('\D','电话:10086')结果['电', '话', ':']
'\w' 匹配字母和数字,等于[A-Za-z0-9] re.findall('\w','alex123,./;;;')结果['a', 'l', 'e', 'x', '1', '2', '3']
'\W' 匹配非英文字母和数字,等于[^A-Za-z0-9] re.findall('\W','alex123,./;;;')结果[',', '.', '/', ';', ';', ';']
'\s' 匹配空白字符 re.findall('\s','3*ds \t\n')结果[' ', '\t', '\n']
'\S' 匹配非空白字符 re.findall('\s','3*ds \t\n')结果['3', '*', 'd', 's']
'\A' 匹配字符串开头
'\Z' 匹配字符串结尾
'\b' 匹配单词的词首和词尾,单词被定义为一个字母数字序列,因此词尾是用空白符或非字母数字符来表示的
'\B' 与\b相反,只在当前位置不在单词边界时匹配
'(?P...)' 分组,除了原有编号外在指定一个额外的别名 re.search("(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{8})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '19930614'}
[] 是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。[\s*]表示空格或者*号。
二.常用的re函数:
方法/属性 作用
re.match(pattern, string, flags=0) 从字符串的起始位置匹配,如果起始位置匹配不成功的话,match()就返回none
re.search(pattern, string, flags=0) 扫描整个字符串并返回第一个成功的匹配
re.findall(pattern, string, flags=0) 找到RE匹配的所有字符串,并把他们作为一个列表返回
re.finditer(pattern, string, flags=0) 找到RE匹配的所有字符串,并把他们作为一个迭代器返回
re.sub(pattern, repl, string, count=0, flags=0) 替换匹配到的字符串
函数参数说明:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标记为,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
repl:替换的字符串,也可作为一个函数
count:模式匹配后替换的最大次数,默认0表示替换所有匹配
例子1
1 #!/usr/bin/python32 import re3 #替换4 phone = '13617002575' #这是我的电话号码'5 print('我的电话号码:',re.sub('#.*','',phone)) #去掉注释6 print(re.sub('\D','',phone))7 #search8 ip_addr = re.search('(\d{3}\.){1,3}\d{1,3}\.\d{1,3}',os.popen('ifconfig').read())9 print(ip_addr)10 #match11 >>> a = re.match('\d+','2ewrer666dad3123df45')12 >>>print(a.group())13 2
获取匹配的函数:
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回包含所有小组字符串的元组,从1到所含的小组
groupdict() 返回以有别名的组的别名为键、以该组截获的子串为值的字典
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配(开始,结束)的位置
三.原生字符串,字符,分组
1.原生字符串
每一次在匹配规则前面加了一个r,表示不转义,使用原生字符串,没用原始字符串,也没出现什么问题。那是因为ASCII 里没有对应的特殊字符,所以正则表达式编译器能够知道你指的是一个十进制数字。但是我们写代码本着严谨简单的原理,最好是都写成原生字符串的格式。
1 import re2 # “\b”在ASCII 字符中代表退格键,\b”在正则表达式中代表“匹配一个单词边界”3 print(re.findall("\bblow", "jason blow cat")) # 这里\b代表退格键,所以没有匹配到4 print(re.findall("\\bblow", "jason blow cat")) # 用\转义后这里就匹配到了 ['blow']5 print(re.findall(r"\bblow", "jason blow cat")) # 用原生字符串后就不需要转义了 ['blow']6 #执行结果:7 []8 ['blow']9 ['blow']
2.编译
如果一个匹配规则要多次使用,可以先将其编译,以后就不用每次去重复写匹配规则:
1 import re2 comp = re.compile(r'\d')3 print(comp.findall('abc1213,-45'))4 #执行结果5 ['1', '2', '1', '3', '4', '5']
3.分组
re模块中分组的作用?
(1)判断是否匹配(2)灵活提取匹配到各个分组的值。
1 >>>import re2 >>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(0)) #返回整体3 34324-d4 >>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(1)) #返回第一组5 34324
6 >>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(2)) #获取第二组7 d8 >>> print(re.search(r'(\d+)-([a-z])','34324-dfsdfs777-hhh').group(3)) #不存在。报错“no such group”9 Traceback (most recent call last):10 File "", line 1, in
11 IndexError: no such group
验证11位手机号:
1import re
2
3
4def main():
5 tel = input("请输入手机号:")
6 ret = re.match(r"^1[35789]\d{9}$", tel)
7
8 ifret:
9 print("匹配成功")
10 else:
11 print("匹配失败")
12
13
14 if __name__ == "__main__":
15 main()
【正则表达式】分析如下:
手机号都为11位,所以必须限定匹配的数字的位数,通过$来限定以9位数字结尾,
又因为手机号都以1开头,所以通过^1限定以1开头,
然后手机号第二位貌似只有3,5,6,7,8,这几个数字,所以通过[3,5,7,8,9]来匹配其中的任一数字,后续推出新的号段,需在这里做添加
最后{9}匹配9个/d。
【补】:/d 表示匹配数字