个人推荐廖雪峰老师的课程,本来这一部分看不太懂,看了他网站上的,感觉明了很多。https://www.liaoxuefeng.com/
正则表达式
正则表达式是一种用来匹配字符串,如判断字符串是否是一个合法的邮箱地址时,如果对内容进行一个个判断的话,
会很麻烦,而正则表达式可以用一种描述性的语言来给字符串定义一个规则,对于符合规则的字符串就匹配成功。
例判断一个字符串是否是合法的Email的方法是:
1:创建一个匹配Email的正则表达式
2:用改正则表达式去匹配用户的输入来判断是否合法
正则表达式中,如果直接给出字符,就是精确匹配。用\d可以匹配数字,\w可以匹配一个字母或数字,所以:
例:'00\d','\d\d\d''\w\w\d'
.可以匹配任意字符,'py.'可以匹配'pyc','py1','py!'等等
要匹配变长的字符,在正则表达式中,用*表示任意个字符,用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符
用{n,m}表示n-m个字符
例:
\d{3}\s+\d{3,8}
其中\s可以匹配一个字符,而\s+表示至少有一个空格
所以,该正则表达式可以匹配以任意空格隔开的带区号的电话号码
若要匹配012-345678,因为-是特殊字符,所以要用\转义
\d{3}\-\d{3,8}
为了更精确的匹配,用[]表示范围,比如:
[0-9a-zA-Z\_]表示匹配一个数字、字母或下划线
[0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串
[a-zA-Z\_][0-9a-zA-Z\_]*表示可以匹配字母或下划线开头,
后接任意个由数字、字母或者下划线组成的字符串
[a-zA-Z\_][0-9a-zA-Z\_]{0,19}更精确的限制了变量的长度是1-20个字符
(开头的一个字母或下划线,后面最多19个字符数字、字母或者下划线)
A|B可以匹配A或B,所以(P|p)ython可以匹配'python'或'Python'
^表示行的开头,^\d表示必须以数字开头
$表示行的结束,\d$表示必须以数字结束
re模块
在python中提供re模块,包含正则表达式的所有功能。注意,python的字符串本身也用\转义
s = 'abc\\-001'
对应的正则表达式字符串是'abc\-001'
所以为了避免因为转义引起的错误,建议使用r为前缀,即
s = r'abc\-001'正则表达式字符串不变
主要的是有match()方法和search()方法,但是两者有一点差别,match函数只能够字符串的开始位置开始匹配,而search是可以匹配字符串的任意位置,但也是返回找到的第一个匹配的模式。在search中应用^表达式,可以和match一样效果。
先看看如何判断正则表达式是否匹配:
import re
s = "my number is 123"
match = re.search(r'\d{3}', s)
print(match)
print(match.group())
<_sre.SRE_Match object; span=(13, 16), match='123'>
123
match()方法是判断是否匹配,如果匹配成功,返回一个match对象,否则返回None。常见的格式:
test = '用户输入的字符串'
if re.match(r'正则表达式', test):
print('ok')
else:
print('failed')
import re
s = "my email is kaiser@jizhi.im"
match = re.search(r'[\w.-]+@[\w.-]+', s)
if match:
print(match.group())
else:
print("match not found")
kaiser@jizhi.im
还可以进一步从匹配字符串中提取符合条件的特定部分,用(),即分组。
import re
2
s = "my email is kaiser@jizhi.im"
3
match = re.search('([\w.-]+)@([\w.-]+)', s)
4
5
if match:
6
print(match.group()) # 完整邮箱地址
7
print(match.group(1)) # 姓名kaiser
8
print(match.group(2)) # 域名jizhi.im
kaiser@jizhi.im
kaiser
jizhi.im
切分字符串
用正则表达式切分字符串比用固定的字符更灵活,
>>> 'a b c'.split(' ')
['a', 'b', '', '', 'c']
无法识别两个连续的空格,而使用正则表达式,则没有这个问题,
>>> re.split(r'\s+', 'a b c')
['a', 'b', 'c']
可以同时切分不同的字符串
>>> re.split(r'[\s\,]+', 'a,b, c d')#,符号需要使用转义\
['a', 'b', 'c', 'd']
如果用户输入了一组标签,可以使用正则表达式来把不规范的输入转化成正确的数组。
捕获
前面的match和search只能返回第一个匹配模式的字符串,如果我们要找到所有匹配的结果,
就需要用到findall()
findall(pattern, string, flags[optional])
如果匹配成功,findall()会返回一个列表,包含所有匹配的字符串,否则返回的是空列表。