1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22在日常生活中,如果访问一个新的网站注册一个用户经常会遇到让填写手机号、邮箱等信息,在填写信息的过程中要对填写的手机号、邮箱进行验证,验证格式是否正确。这个验证是如何实现的呢?就是本节要讲的正则表达式。
在Python中提供了re(regular expression简写)正则表达式模块,能够非常方便的使用正则表达式进行一些常用的规则验证。
常用方法:
match(正则表达式,待匹配字符串)方法
match方法用来进行正则匹配检查,如果待匹配字符串能够匹配正则表达式,则match方法返回匹配对象Match Object,否则返回None。match方法采用从左往右逐项比较。
group()方法
匹配对象Macth Object具有group方法,用来返回字符串的匹配部分。
示例:匹配以chinahadoop开头的字符串
import re
#匹配以chinahadoop开头的字符串
result = re.match("chinahadoop","")
#打印匹配出来的内容
print(result.group())
运行结果:
chinahadoop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63字符 描述
. 匹配除“\n”之外的任意单个字符
\d 匹配0到9之间的一个数字,等价于[0-9]
\D 匹配一个非数字字符,等价于[^0-9]
\s 匹配任意空白字符,如空格、制表符“\t”、换行“\n”等
\S 匹配任意非空白字符
\w 匹配任意字母或者数字或下划线,如a-z,A-Z,0-9,_等
\W 匹配任意非单词字符,等价于[^ a-zA-Z0-9_]
[ ] 匹配[ ]中列举的字符
^ 取反
示例:使用“.”匹配除换行符\n之外的任意单个字符
import re
# . 匹配除“\n”之外的任意单个字符
rs = re.match(".","1")
print(rs.group())
rs = re.match(".","a")
print(rs.group())
rs = re.match(".","abc") #只匹配单个字符
print(rs.group())
rs = re.match("...","abc") #用3个点匹配3个字符
print(rs.group())
运行结果:
1
a
a
abc
示例:\w匹配单词字符(包括 _ )
rs = re.match("\w","a")
print(rs.group())
rs = re.match("\w","A")
print(rs.group())
rs = re.match("\w","1")
print(rs.group())
rs = re.match("\w","_")
print(rs.group())
rs = re.match("\w","*") #将不会匹配*,返回none
print(type(rs))
运行结果:
a
A
1
_
示例:匹配[ ]中列举的字符,列举的字符之间相当于是或的关系
#匹配以h或者H开头的字符串
rs = re.match("[Hh]", "hello")
print(rs.group())
# 匹配0到9任意一个数字方法一
rs = re.match("[0123456789]", "3")
print(rs.group())
# 匹配0到9任意一个数字方法二
rs = re.match("[0-9]", "3")
print(rs.group())
运行结果:
h
3
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83在使用正则表达式的过程中,不可能只针对单个字符匹配,很多时候要对多次出现的字符进行匹配,下面介绍正则表达式的数量表示方法。
字符 描述
* 一个字符可以出现任意次,也可以一次都不出现
+ 一个字符至少出现一次
? 一个字符至多出现一次
{m} 一个字符出现m次
{m,} 一个字符至少出现m次
{m,n} 一个字符出现m到n次
示例:“*”一个字符可以出现任意次,也可以一次都不出现
rs = re.match("1\d*","1234abc")#匹配以1开头,后边是任意多个数字,数字有其他字符,也只匹配数字
print(rs.group())
运行结果:
1234
示例:"+"一个字符至少出现一次
#字符开头至少出现一个数字
rs = re.match("\d+","1abc") #开头只出现1个数字,符合规则
print(rs.group())
rs = re.match("\d+","123abc") #开头出现多个数字,符合规则
print(rs.group())
运行结果:
1
123
示例:“?”一个字符至多出现一次
#匹配开头出现一次的数字字符
rs = re.match("\d?","1abc")
print(rs.group())
#开头数字至多出现一次
rs = re.match("\d?","123abc") #在1之后的所有数字字符都不会匹配上
print(rs.group())
运行结果:
1
1
示例:{m} 出现m次
rs = re.match("\d{3}","123abc") #要连续出现3次数字
print(rs.group())
#要连续出现4次数字,字符串中只出现了3次,与规则不匹配
rs = re.match("\d{4}","123abc")
print(type(rs))
运行结果:
123
示例:{m,} 至少出现m次
rs = re.match("\d{0,}","123abc") #等价于*,0次或者多次
print(rs.group())
rs = re.match("\d{1,}","123abc") #等价于+,至少出现一次
print(rs.group())
rs = re.match("\d{0,1}","123abc") #等价于?,至多1次,0次或者1次
print(rs.group())
运行结果:
123
123
1
综合练习:匹配一个手机号
手机号一共11位,第1位是1,第2位是3、5、7、8,第3位到第11位是0-9的数字
代码实现:
rs = re.match("1[3578]\d{9}","13612345678") #匹配成功
print(rs.group())
#用一个错误的手机号测试
rs = re.match("1[3578]\d{9}","14612345678") #匹配失败,第2位没有出现3、5、7、8
print(type(rs))
#11位电话号码+字符测试
rs = re.match("1[3578]\d{9}","13612345678abc")
print(rs.group())
#没有限制边界,也会认为是合法的手机号,后续的“边界表示”课时会介绍如何限定正则表达式的开始和结束边界
运行结果:
13612345678
13612345678
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59接下来学习正则表达式的边界表示,边界表示就是在写正则表达式的时候,限制匹配的字符串的开始和结束边界。
字符 描述
^ 匹配字符串开头
$ 匹配字符串结尾
\b 匹配一个单词的边界
\B 匹配非单词边界
注意:边界字符只用于描述边界信息,不能用于字符的匹配。
示例:完善之前课时中关于手机号码匹配的示例,在匹配超过11位的手机号,或者11位的手机号后边还有其他字符的情况,正则表达式也能够匹配成功,这种情况是不允许的。这种情况就需要限制手机号的结尾。
#使用$限制匹配的字符串以11位数字组成,结尾不能添加其他字符
rs = re.match("1[3578]\d{9}$","13612345678")
print(rs.group()) #匹配正确的手机号
#手机号末尾添加字符串将匹配失败
rs = re.match("1[3578]\d{9}$","13612345678abc")#匹配失败
print(type(rs)) #空类型
运行结果:
13612345678
(使用match方法进行正则匹配“^”匹配开头不是很明显,因为match本身就是从左向右顺序匹配的)
示例:邮箱匹配
#邮箱地址以3到10个单词字符开始,以@结束
rs = re.match("\w{3,10}@$","hello_123@")
print(rs)
rs = re.match("\w{3,10}@$","he@")
print(rs)
rs = re.match("\w{3,10}@$","hello_12345645@")
print(rs)
rs = re.match("\w{3,10}@$","hello_123@haha")
print(rs)
运行结果:
<_sre.SRE_Match object; span=(0, 17), match='hello_123@'>
None
None
None
问题1:随意用一个字母代替邮箱中的“.”也会匹配成功
rs = re.match("\w{3,10}@$","hello_123@163hcom")
print("匹配结果:%s"%rs)
运行结果:
匹配结果:<_sre.SRE_Match object; span=(0, 17), match='hello_123@163hcom'>
原因是:在正则表达式中“.”有特殊的含义,表示除\n之外的任意字符
解决办法:使用转义字符\ 标识“.”是普通字符“.”
rs = re.match("\w{3,10}@163\.com$","hello_123@")
print("匹配结果1:%s"%rs)
rs = re.match("\w{3,10}@163\.com$","hello_123@163hcom")
print("匹配结果2:%s"%rs)
运行结果:
匹配结果1:<_sre.SRE_Match object; span=(0, 17), match='hello_123@'>
匹配结果2:None
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50贪婪模式:
正则引擎默认是贪婪模式,尽可能多的匹配字符。
非贪婪模式
与贪婪模式相反,尽可能少的匹配字符
在表示数量的“*”,“?”,“+”,“{m,n}”符号后面加上?,使贪婪变成非贪婪。
示例:贪婪模式演示
rs = re.findall("hello\d*", "hello12345") #任意多个数字
print(rs)
rs = re.findall("hello\d+", "hello12345")#至少出现一次数字
print(rs)
rs = re.findall("hello\d?", "hello12345")#至多出现一次数字
print(rs)
rs = re.findall("hello\d{2,}", "hello12345") #至少出现2次数字
print(rs)
rs = re.findall("hello\d{1,3}","hello12345") #出现1到3次数字
print(rs)
运行结果:
['hello12345']
['hello12345']
['hello1']
['hello12345']
['hello123']
从运行结果看每个正则表示都尽可能多的匹配了字符
示例:非贪婪模式,在贪婪模式的正则表达式表示数量的符号后边添加?切换为非贪婪模式
rs = re.findall("hello\d*?", "hello12345") #任意多个数字,也可以没有
print(rs)
rs = re.findall("hello\d+?", "hello12345") #至少一个,匹配了1个
print(rs)
rs = re.findall("hello\d??", "hello12345") #至多一个,可以没有
print(rs)
rs = re.findall("hello\d{2,}?", "hello12345") #最少两个,匹配了两个
print(rs)
rs = re.findall('hello\d{1,3}?', 'hello12345') #1到3个,匹配了1个
print(rs)
运行结果:
['hello']
['hello1']
['hello']
['hello12']
['hello1']
分享到:
小象学院python数据分析课程怎么样_小象学院大数据分析集训营试听知识点整理-正则表达式...