1.模块的功能:
- 为了方便管理程序,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。
- 在Python中有许多模块,我们可以导入模块来提高自己的编程效率,也能够更好地实现程序的功能。
2.正则
正则是描述一类字符或者字符串的规则,嵌套在re模块中,如果导入re模块就是使用正则取匹配字符或字符串中的内容。
2.1 字符组
字符组:[] 写在中括号中的内容都可以出现在字符串中
[0-9] 匹配数字
[a-z] 匹配小写字母 ASCII码97-122
[A-Z] 匹配大写字母 ASCII码65-90
[a-zA-Z] 匹配大小写字母
[a-zA-Z0-9] 匹配大小写字母+数字
[a-zA-Z0-9_] 匹配数字字母下划线
2.2 元字符
- \w 匹配数字字母下划线
- \d 匹配所有的数字
- \s 匹配所有的空白符 回车/制表符
- \t 匹配一个制表符
- \n 匹配回车
- \W 匹配非字母数字下划线
- \D 匹配非数字
- \S 匹配非空白/回车/制表符
- [\s\S]、[\d\D]、[\w\W]匹配所有的字符
- ^ 匹配一个字符串的开始
- $ 匹配一个字符串的结尾
- .匹配除换行符以外的所有字符
- [^]匹配非字符组内容,例如[^a]就是匹配字符串中不是a的内容
- 有一些有特殊意义的元字符进入字符组会回复它本来的意义:. | [] () / ? -(在字符组中有特殊意义,需要转义)
- a|b 或 符合a规则或者b规则的都可以匹配,如果a规则是b规则的一部分,且a规则比b规则更长,应当将a规则写在前面,将更复杂,更长的规则写在前面。
2.3 量词
- {n}表示这个量词之前的字符出现n次
- {n,}表示这个量词之前的字符至少出现n次
- {n, m}表示这个量词之前的字符出现n-m次
- ?表示匹配量词之前的字符出现0次或者1次 表示可有可无
- +表示匹配量词之前的字符出现 1次或者多次
- *表示匹配量词之前的字符出现0次或者多次
2.4 分组
- 对于正则表达式而言,有时候我们需要进行分组,来整体约束某一字符出现的次数,如(\.[\w+])?
2.5 正则练习
1 匹配整数 \d+
2 匹配小数 \d+\.\d+
3 匹配整数或者小数 \d+(\.\d+)?
4 匹配身份证号码:[1-9]\d{16}[\dx]|[1-9]\d{14}
5 匹配年月日 :^[1-9]\d{0,3}-(1[0-2]|0?[1-9])-(3[01]|[12]\d|0?[1-9])$
6 匹配QQ号: [1-9]\d{4-11}
7 11位电话号码:1[3-9]\d{9}
8 匹配验证码:[\da-zA-Z]{4}
9 匹配邮箱:[0-9a-zA-Z][\w\-.]+@[a-zA-Z.0-9\-]+(\.[a-zA-Z0-9\-]+)*\.[a-zA-Z0-9]{2,6}
10 匹配内层没有小括号的表达式:\([^()]\)
2.6 正则表达式的特点
正则表达式的匹配特点:贪婪匹配
- 贪婪匹配会在允许的范围内取最长的结果
- 非贪婪模式/惰性匹配:在量词的后面加上?即在范围内尽量少的匹配。
3.re模块
3.1 re模块功能之查找(使用模块前必须import re导入模块)
# findall
ret = re.findall('\d+', 'sjkdfa112shfa998')
print(ret)
# 结果:['112', '998']
# search
ret = re.search('\d+', 'sjkdfa112shfa998')
if ret: # 这里的ret只是正则结果的内存地址
print(ret.group()) # 通过ret.group()获取真正的结果
# 结果:['1', '1', '2', '9', '9', '8']
# match 从头开始匹配,相当于search中的正则表达式加上一个^
ret = re.match('\d', '122sjkdfashfa998')
print(ret)
# 结果:112
3.2 切分
s = 'adkf12fag34'
ret = re.split('\d+',s)
print(ret)
# 结果:['adkf', 'fag', '']
3.3 替换
1 # sub
2 ret = re.sub('\d+', 'H', 'alex83taibai40', 1)
3 print(ret)
4 # 结果:alexHtaibai40
# subn 返回一个元组,第二个元素是替换的次数
ret = re.subn('\d+', 'H', 'alex83taibai40')
print(ret)
# 结果:('alexHtaibaiH', 2)
3.4 编译
compile 节省使用正则表达式解决问题的时间,将正则表达式编译成字节码,在多次使用时不会多次编译。
1 ret = re.compile('\d+')
2 res = ret.findall('alex83taibai40')
3 res_1 = ret.findall('213afda324')
4 res_2 =ret.search('4343faag')
5 print(res, res_1, res_2)
3.5 finditer
# finditer 节省使用正则表达式解决问题的空间
ret = re.finditer('\d+', 'alex342fa5')
print(ret)
for i in ret:
print(i.group())
4.分组在re模块中的使用
4.1 优先匹配分组中的内容
1 import re
2 s = '<a>wahaha</a>'
3 ret = re.search('<(\w+)>(\w+)</(\w+)>',s)
4 print(ret.group()) # 括号内默认为0,打印所有的结果
5 print(ret.group(1)) # 数字参数代表的是取对应分组中的内容
6 print(ret.group(2))
7 print(ret.group(3))
8 # 结果:
9 <a>wahaha</a>
10 a
11 wahaha
12 a
4.2 findall中的分组优先:优先显示分组中的内容:
1 import re
2 ret = re.findall('\d+(\.\d+)?', '1.234*4.3')
3 print(ret)
4 # 结果:['.234', '.3']
findall中的分组优先:优先显示分组中的内容
1 import re
2 ret = re.findall('\d+(?:\.\d+)?', '1.234*4.3')
3 print(ret)
4 # 结果:['1.234', '4.3']
4.3 split中的分组
1 import re
2 s = 'adkf12fag34'
3 ret = re.split('\d+',s)
4 print(ret)
5
6 s = 'adkf12fag34'
7 ret = re.split('(\d+)',s)
8 print(ret)
9
10 # 结果:
11 ['adkf', 'fag', '']
12 ['adkf', '12', 'fag', '34', '']
4.4 分组的命名
1 import re
2 s = '<a>wahaha</a>'
3 ret = re.search('>(?P<con>\w+)<',s)
4 print(ret.group(1))
5 print(ret.group('con'))
6 # 结果:
7 wahaha
8 wahaha
1 s = '<a>wahaha</b>' 2 pattern = '<(\w+)>(\w+)</(\w+)>' 3 ret = re.search(pattern, s) 4 print(ret.group(1) == ret.group(3)) 5 # 结果:False
注:使用前面的分组,要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致。
1 s = '<a>wahaha</b>' 2 pattern = '<(?P<tab>\w+)>(\w+)</(?P=tab)>' 3 ret = re.search(pattern, s) 4 print(ret)
4.5 正则的表达应该更精确
1 ret = re.findall(r"\d+", "1-2*(60+(-40.35/5)-(-4*3))")
2 print(ret) # 结果将不应该匹配的小数也匹配出来了
3 # 结果:['1', '2', '60', '40', '35', '5', '4', '3']
4
5 # 应该精确取到整数
6 ret = re.findall(r"\d+\.\d+|\d+", "1-2*(60+(-40.35/5)-(-4*3))")
7 print(ret)
8 # 结果:['1', '2', '60', '40.35', '5', '4', '3']
9
10 # 使用分组优先显示整数
11 ret = re.findall(r"\d+\.\d+|(\d+)", "1-2*(60+(-40.35/5)-(-4*3))")
12 ret.remove('')
13 print(ret)
14 # 结果:['1', '2', '60', '5', '4', '3']
来源:https://www.cnblogs.com/Studying-Du/p/12361056.html