3. Python基础

3.1. 脚本 [bases_01]:基础操作
脚本 [bases_01] 展示了 Python 的基本特性。
# ----------------------------------
def affiche(chaine):
# 显示字符串
print("chaine=%s" % chaine)
# ----------------------------------
def affiche_type(variable):
# 显示变量类型
print("type[%s]=%s" % (variable, type(variable)))
# ----------------------------------
def f1(param):
# 将10加到参数上
return param + 10
# ----------------------------------
def f2():
# 返回一个包含3个值的元组
return "un", 0, 100
# -------------------------------- 主程序 ------------------------------------
# 这是一条注释
# 未声明的变量被使用
nom = "dupont"
# 屏幕输出
print("nom=%s" % nom)
# 包含不同类型元素的列表
liste = ["un", "deux", 3, 4]
# 其元素个数
n = len(liste)
# 一个循环
for i in range(n):
print("liste[%d]=%s" % (i, liste[i]))
# 使用元组初始化两个变量
(chaine1, chaine2) = ("chaine1", "chaine2")
# 两个字符串的拼接
chaine3 = chaine1 + chaine2
# 显示结果
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))
# 使用函数
affiche(chaine1)
# 变量的类型可能已知
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)
# 变量的类型在运行时可能会改变
n = "a changé"
affiche_type(n)
# 函数可以返回结果
res1 = f1(4)
print("res1=%s" % res1)
# 函数可以返回一组值
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))
# 这些值本可以被存入一个变量中
liste = f2()
for i in range(len(liste)):
print("liste[%s]=%s" % (i, liste[i]))
# 测试
for i in range(len(liste)):
# 仅显示字符串
if type(liste[i]) == "str":
print("liste[%s]=%s" % (i, liste[i]))
# 其他测试
for i in range(len(liste)):
# 仅显示大于10的整数
if type(liste[i]) == "int" and liste[i] > 10:
print("liste[%s]=%s" % (i, liste[i]))
# 一个 while 循环
liste = (8, 5, 0, -2, 3, 4)
i = 0
somme = 0
while i < len(liste) and liste[i] > 0:
print("liste[%s]=%s" % (i, liste[i]))
somme += liste[i] # somme=somme+liste[i]
i += 1 # i=i+1
print("somme=%s" % somme)
# 程序结束
注释
- 第 2 行:关键字 def 定义了一个函数;
- 第2行:该函数接收参数[chaine]。未指定参数类型。Python仅使用按值传递。具体方式因数据类型而异:
- 对于简单类型(数字、布尔值等),该值即数据所封装的值(4、True 等);
- 对于复杂类型(列表、类等),该值即为数据的内存地址;
- 第 3-4 行:函数体内容。其向右缩进一个制表符。正是这种缩进与 def 语句中的冒号 (:) 共同定义了函数体内容。此规则适用于所有包含内容的语句:if、else、while、for、try、except;
- 第 4 行:此处使用的语法是 [print('text1%F1text2%F2…' % data1, data2)]:
- [%Fi](此处为 %s)是显示格式:
- %s(字符串):用于字符串;
- %d(十进制):用于带符号的十进制整数;
- %f (float):用于实数的十进制格式;
- %e (指数) : 实数的指数格式;
- …
- [data1, data2…] 是需要显示其值的表达式:
- [data1] 将以 F1 的格式显示;
- [data2] 将以 F2 的格式显示;
- …
- 第 10 行:Python 内部管理变量的类型。可以通过函数 type(variable) 获取变量的类型,该函数返回类型为 'type' 的变量。表达式 '%s' % (type(variable)) 是一个字符串,表示变量的类型;
- 第25行:主程序。它通常(但并非必须)位于脚本中所有函数定义之后。其内容不进行缩进;
- 第 28 行:在 Python 中,无需声明变量。Python 区分大小写。变量 Nom 与变量 nom 是不同的。 字符串可以用双引号 " 或单引号 ' 包围。因此可以写成 'dupont' 或 "dupont";
- 第 34 行:元组 (1,2,3)(注意圆括号)与列表 [1,2,3](注意方括号)之间存在差异。 元组是不可变的,而列表是可变的。在两种情况下,第 i 个元素都表示为 [i];
- 第 40 行:range(n) 是元组 (0,1,2,…,n-1);
- 第 41 行:格式 %d 用于有符号整数;
- 第 74 行:len(var) 是集合 var(元组、列表、字典等)的元素个数;
- 第 84 行:结构 [for in …] 用于遍历可迭代结构。列表和元组都是可迭代元素;
- 第 86 行:其他布尔运算符包括 or 和 not;
- 第 93 行:计算列表中所有大于 0 的数字之和;
屏幕输出结果如下:
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_01.py
nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<class 'int'>
type[chaine1]=<class 'str'>
type[['un', 'deux', 3, 4]]=<class 'list'>
type[a changé]=<class 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13
Process finished with exit code 0
3.2. 脚本 [bases_02]:格式化字符串
Python 3 引入了一种新的字符串格式化方式:
# 格式字符串
# 格式遵循C语言规范
# 整数
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
# 浮点数
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
# 字符串
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
# 格式化字符串可赋值给变量
str3=f"[{str2:20.10s}]"
print(str3)
格式化字符串的语法如下:
其中:
- [expri]:一个表达式;
- [formati]:表达式 [expri] 的格式。这些格式采用 C 语言的格式:
- %d:用于整数;
- %f:实数的十进制表示;
- %e:实数的指数表示法;
- %s:用于字符串。当未为 [expri] 指定格式时,将使用此格式;
- %nd, %nf, %ns:在 n 个字符内显示 [expri]:字符串要么被截断,要么用空格补齐;
- 第 7 行:[04d],4 字符的整数,左侧用零补齐;
- 第 11 行:[8.2f],8 字符的十进制实数,小数点后有 2 位;
- 第 12 行:[.3e],指数形式的实数,尾数有 3 位小数;
- 第 18 行:[20.10s],字符串的前 10 个字符,用空格补足至 20 个字符;
执行结果如下:
3.3. 脚本 [bases_03]:类型转换
此处关注的是涉及 str(字符串)、int(整数)、float(浮点数)、bool(布尔值)类型数据的类型转换。
# 类型转换
# int --> str, float, bool
x = 4
print(x, type(x))
x = str(4)
print(x, type(x))
x = float(4)
print(x, type(x))
x = bool(4)
print(x, type(x))
# bool --> int, float, str
x = True
print(x, type(x))
x = int(True)
print(x, type(x))
x = float(True)
print(x, type(x))
x = str(True)
print(x, type(x))
# str --> int, float, bool
x = "4"
print(x, type(x))
x = int("4")
print(x, type(x))
x = float("4")
print(x, type(x))
x = bool("4")
print(x, type(x))
# float 转 str、int、bool
x = 4.32
print(x, type(x))
x = str(4.32)
print(x, type(x))
x = int(4.32)
print(x, type(x))
x = bool(4.32)
print(x, type(x))
# 类型转换错误处理
try:
x = int("abc")
print(x, type(x))
except ValueError as erreur:
print(erreur)
# 各种情况
x = bool("abc")
print(x, type(x))
x = bool("")
print(x, type(x))
x = bool(0)
print(x, type(x))
x = None
print(x, type(x))
x = bool(None)
print(x, type(x))
x = bool(0.0)
print(x, type(x))
# 所有数据都是类实例,因此具有方法
# 字符串
str1 = "abc"
print(str1.capitalize())
# 整数
int1 = 4
print(int1.bit_length())
# 布尔值
bool1=True
print(bool1.conjugate())
# 实数
float1=8.2
print (float1.is_integer())
可能发生多种类型转换。其中某些操作可能会失败,例如第 46-47 行尝试将字符串 'abc' 转换为整数。我们通过结构体 try / except 处理了该错误。该结构体的通用形式
如下:
try:
actions
except Exception as ex:
actions
finally:
actions
如果 try 块中的任一操作抛出异常(报告错误),程序将立即跳转到 except 子句。如果 try 块中的操作未抛出异常,则忽略 except 子句。 指令 except 的属性 Exception 和 ex 为可选。 当这些属性存在时,Exception 指定由 except 语句捕获的异常类型,而 ex 包含发生的异常。 如果要在同一个 try 中处理不同类型的异常,可以使用多个 except 指令。
finally 语句是可选的。如果存在该语句,无论是否发生异常,finally 中的操作都会始终执行。
我们稍后将再次讨论异常。
第 49-61 行展示了将 str、int、float、NoneType 类型的数据转换为布尔值的多种尝试。这种转换始终是可行的。 规则如下:
- 当 i 等于 0 时,bool(int i) 的值为 False,其他情况下均为 True;
- bool(float f) 的值为:若 f 等于 0.0,则为 False;其他所有情况下均为 True;
- bool(str 字符串) 的值为:若字符串长度为 0,则为 False;其他情况下均为 True;
- bool(None) 返回 False。None 是一个特殊值,表示该变量存在但没有值。
屏幕显示结果如下:
需要注意的是,所有数据都是对象,即类的实例。这意味着它们可能具有方法。代码第 63-75 行展示了这一点。我们在此不打算解释所用方法的功能,仅旨在说明它们的存在。
3.4. 脚本 [bases_04]:变量的作用域
脚本 [bases_04] 表明 Python 没有“块作用域变量”的概念:
# 变量作用域
i = 4
if True:
i += 1
j = 7
print(f"i={i}, j={j}")
结果
注释
结果表明了两点:
- 第 4 行:[if] 代码块中的变量 [i] 与第 2 行中使用的变量 i 相同;
- 第6行:变量[j]是[if]代码块中初始化的那个;
在某些需要显式声明变量的语言中,块内定义的变量(如第3-5行所示)在块外部是不可见的。但在Python中,情况并非如此。
3.5. 脚本 [bases_05]:列表 - 1
脚本 [bases_05] 如下:
# 一维数组
# 初始化
list1 = [0, 1, 2, 3, 4, 5]
# 遍历 - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
print(f"list1[{i}]={list1[i]}")
list1[1] = 10
# 遍历 - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
print(element)
# 添加两个元素
list1[len(list1):] = [10, 11]
# %s 格式可将列表显示在一行上
print("%s" % list1)
# 删除最后两个元素
list1[len(list1) - 2:] = []
# 默认格式可将列表显示在一行上
print(f"{list1}")
# 在列表开头添加一个列表
list1[:0] = [-10, -11, -12]
print(f"{list1}")
# 在列表中间插入两个项目
list1[3:3] = [100, 101]
print(f"{list1}")
# 删除列表中间的两个元素
list1[3:4] = []
print(f"{list1}")
注:
- 表记法 tableau[i:j] 表示数组的第 i 到 j-1 个元素;
- 符号 [i:] 表示数组中的第 i 个及后续元素;
- 符号 [:i] 表示数组的第 0 到 i-1 个元素;
- 第 19 行:print (%s) % (list1) 输出字符串:“[ list1[0], list1[2]…, list1[n-1]]”;
- 第 24 行:print ('f{list1}') 的写法效果相同;
结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_05.py
list1 a 6 éléments
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 éléments
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]
Process finished with exit code 0
3.6. 脚本 [bases_06]:列表 - 2
利用列表的某些方法,上述代码可以改写为(bases_06):
# 一维列表
# 初始化
list1 = [0, 1, 2, 3, 4, 5]
# 遍历 - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
print(f"list1[{i}]={list1[i]}")
# 修改一个元素
list1[1] = 10
# 遍历 - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
print(element)
# 添加两个元素
list1.extend([10, 11])
print(f"{list1}")
# 删除最后两个元素
del list1[len(list1) - 2:]
print(f"{list1}")
# 在列表开头添加一个元组
for i in (-12, -11, -10):
list1.insert(0, i)
print(f"{list1}")
# 在列表中间插入
for i in (101, 100):
list1.insert(3, i)
print(f"{list1}")
# 从列表中间删除
del list1[3:4]
print(f"{list1}")
所得结果与前一版本相同。
3.7. 脚本 [bases_07]:字典
脚本 [bases_07] 演示了如何定义和利用字典(有时也称为关联数组)。
# 一个函数,用于检查键 mari 是否存在于字典 conjoints 中
def existe(conjoints, mari):
if mari in conjoints:
print(f"La clé [{mari}] existe associée à la valeur [{conjoints[mari]}]")
else:
print(f"La clé [{mari}] n'existe pas")
# ----------------------------- 主函数
# 一个字典
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}
# 遍历 - 1
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
for (clé, valeur) in conjoints.items():
print(f"conjoints[{clé}]={valeur}")
# 字典键列表
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")
# 字典值列表
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")
# 查找键
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")
# 删除键值对
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")
# 字典的键和值不是列表
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")
# 可以将其转换为列表
lclés = list(clés)
print(f"clés : {type(lclés)}, {lclés}")
lvaleurs = list(valeurs)
print(f"valeurs : {type(lvaleurs)}, {lvaleurs}")
注:
- 第 11 行:字典的硬编码定义;
- 第 15 行:conjoints.items() 将字典中 (键,值) 对的列表转换为关联数组;
- 第 20 行:conjoints.keys() 返回联合字典的键;
- 第 25 行:conjoints.values() 返回联合字典的值;
- 第 3 行:mari in conjoints 返回 True,如果键 mari 存在于字典 conjoints 中,否则返回 False;
- 第 36 行:字典可以显示在一行中。
结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_07.py
Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
liste des clés-------------
dict_keys(['Pierre', 'Paul', 'Jacques', 'Jean'])
liste des valeurs------------
dict_values(['Gisèle', 'Virginie', 'Lucette', ''])
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
{'Pierre': 'Gisèle', 'Paul': 'Virginie', 'Jacques': 'Lucette'}
type des clés : <class 'dict_keys'>
type des valeurs : <class 'dict_values'>
clés : <class 'list'>, ['Pierre', 'Paul', 'Jacques']
valeurs : <class 'list'>, ['Gisèle', 'Virginie', 'Lucette']
Process finished with exit code 0
注:
- 请注意结果的第16-17行,字典的键和值并非构成一个列表,而是一个名为“dict_keys”的类型;
- 第18-19行:只需简单更改类型,即可将其转换为类型[list];
3.8. [bases_08] 脚本:元组
元组与列表有相似之处,但不可修改:
# 元组
# 初始化
tuple1 = (0, 1, 2, 3, 4, 5)
# 遍历 - 1
print(f"tuple1 a {len(tuple1)} elements")
for i in range(len(tuple1)):
print(f"tuple1[{i}]={tuple1[i]}")
# 遍历 - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
print(element)
# 元组可以显示在一行中
print(f"tuple1={tuple1}")
# 元组不可修改
tuple1[0] = 10
结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py
tuple1 a 6 elements
tuple1[0]=0
tuple1[1]=1
tuple1[2]=2
tuple1[3]=3
tuple1[4]=4
tuple1[5]=5
tuple1 a 6 elements
0
1
2
3
4
5
tuple1=(0, 1, 2, 3, 4, 5)
Traceback (most recent call last):
File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py", line 19, in <module>
tuple1[0] = 10
TypeError: 'tuple' object does not support item assignment
Process finished with exit code 1
注:
- 结果中的第17-20行:表明元组不可修改。
3.9. 脚本 [bases_09]:多维列表和字典
脚本 [bases_09] 演示了如何定义和使用多维列表或字典:
# 多维列表
# 初始化
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
# 遍历
for i1 in range(len(multi)):
for i2 in range(len(multi[i1])):
print(f"multi[{i1}][{i2}]={multi[i1][i2]}")
# 单行显示
print(f"multi={multi}")
# 多维字典
# 初始化
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}
# 遍历
for (clé, valeur) in multi.items():
for i2 in range(len(valeur)):
print(f"multi[{clé}][{i2}]={multi[clé][i2]}")
# 单行显示
print(f"multi={multi}")
注释
- 第 7 行:multi[i1] 是一个列表;
- 第 18 行:value 是一个列表;
结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_09.py
multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi=[[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
multi[zéro][0]=0
multi[zéro][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24
multi={'zéro': [0, 1], 'un': [10, 11, 12, 13], 'deux': [20, 21, 22, 23, 24]}
Process finished with exit code 0
3.10. 脚本 [bases_10]:字符串与列表之间的关联
脚本 [bases_10] 演示了如何将字符串中以相同分隔符分隔的元素提取到列表中。
# 字符串转列表
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))
# 列表显示
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
# 列表转字符串
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")
# 添加一个空字段
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")
# 列表显示
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
# 再次添加一个空字段
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")
# 显示列表
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")
注:
- 第 3 行:方法 chaine.split(分隔符) 将字符串 chaine 分割为由 séparateur 分隔的元素,并将其以列表形式返回。 因此,表达式 '1:2:3:4'.split(":") 的值为列表 ('1','2','3','4');
- 第 11 行:'separateur'.join(liste) 的值为字符串 'liste[0]+separateur+liste[1]+separateur+…'。
结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_10.py
<class 'list'>
liste a 4 éléments
liste=['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
liste a 5 éléments
liste=['1', '2', '3', '4', '']
chaine=1:2:3:4::
liste a 6 éléments
liste=['1', '2', '3', '4', '', '']
Process finished with exit code 0
3.11. 脚本 [bases_11]:正则表达式
脚本 [bases_11] 演示了如何使用正则表达式:
# 导入正则表达式模块
import re
# --------------------------------------------------------------------------
def compare(modèle, chaine):
# 将字符串 [chaîne] 与模板 [modèle] 进行比较
# 显示结果
print(f"\nRésultats({chaine},{modèle})")
match = re.match(modèle, chaine)
if match:
print(match.groups())
else:
print(f"La chaîne [{chaine}] ne correspond pas au modèle [{modèle}]")
# Python 正则表达式
# 提取字符串中的各个字段
# 模式:由任意字符包围的一串数字
# 我们只想提取数字序列
modèle = r"^.*?(\d+).*?$"
# 将字符串与模式进行匹配
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")
# 模式:由任意字符包围的一串数字
# 需要提取数字序列及其前后相邻的字段
modèle = r"^(.*?)(\d+)(.*?)$"
# 将字符串与模式进行匹配
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")
# 模式:日期格式为 dd/mm/yy
modèle = r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modèle, "10/05/97")
compare(modèle, " 04/04/01 ")
compare(modèle, "5/1/01")
# 模式——一个十进制数
modèle = r"^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modèle, "187.8")
compare(modèle, "-0.6")
compare(modèle, "4")
compare(modèle, ".6")
compare(modèle, "4.")
compare(modèle, " + 4")
# 结束
注:
- 请注意第 2 行导入的 [re] 模块。该模块包含正则表达式管理函数;
- 第 10 行:将字符串与正则表达式(模式)进行比较,若字符串匹配模式则返回布尔值 True,否则返回 False;
- 第12行:match.groups()是一个元组,其元素是字符串中与正则表达式中括号包围的部分相匹配的部分。在模式中:
- ^.*?(\d+).*?,match.groups() 将是一个单元素元组,因为其中有一个括号;
- ^(.*?)(\d+)(.*?)$,match.groups() 将是一个包含 3 个元素的元组,因为有三个括号;
- 第 21 行:字符串形式的正则表达式记为 r"xxx"。正是 r 符号使该字符串成为正则表达式;
正则表达式允许我们验证字符串的格式。因此,我们可以检查表示日期的字符串是否符合 dd/mm/yy 格式。为此,我们使用一个模式并将字符串与该模式进行比较。因此,在这个示例中,j、m 和 a 必须是数字。 因此,有效的日期格式模式为“\d\d/\d\d/\d\d”,其中符号 \d 表示一个数字。模式中可使用的符号如下:
字符 | 描述 |
\ | 将后续字符标记为特殊字符或字面字符。例如,“n”表示字符“n”,而“\n”表示换行符。字符序列“\\”表示“\”,而“\("表示“(”。 |
^ | 表示字符串的开头。 |
$ | 表示字符串的结尾。 |
* | 匹配前一个字符,零次或多次。因此,“zo*”匹配“z”或“zoo”。 |
+ | 匹配前一个字符,一次或多次。因此,“zo+”匹配“zoo”,但不匹配“z”。 |
? | 匹配前一个字符,零次或一次。例如,“a?ve?”匹配“lever”中的“ve”。 |
. | 匹配任何单个字符,但不包括换行符。 |
(模式) | 查找 modèle 并存储匹配结果。匹配的子字符串可从集合 match.groups() 中提取。若要查找括号 ( ) 内的字符,请使用 "\(" 或 "\)"。 |
x|y | 匹配 x 或 y。例如,“z|foot”匹配“z”或“foot”。“(z|f)oo”匹配“zoo”或“foo”。 |
{n} | n 是一个非负整数。精确匹配 n 倍的该字符。例如,“o{2}”不匹配“Bob,”中的“o”,而是匹配“fooooot”中的前两个“o”。 |
{n,} | n 是一个非负整数。匹配该字符至少 n 次。 例如,“o{2,}”不匹配“Bob”中的“o”,而是匹配“fooooot”中的所有“o”。“o{1,}”等同于“o+”,而“o{0,}”等同于“o*”。 |
{n,m} | m 和 n 是非负整数。 表示该字符出现次数不少于 n 次,且不超过 m 次。例如,“o{1,3}”匹配“foooooot”中的前三个“o”,而“o{0,1}”等同于“o?”。 |
[xyz] | 字符集。匹配所列出的任意一个字符。例如,“[abc]”匹配“plat”中的“a”。 |
[^xyz] | 否定字符集。匹配所有未列出的字符。例如,“[^abc]”匹配“plat”中的“p”。 |
[a-z] | 字符范围。匹配指定字符序列中的任何字符。例如,“[a-z]”匹配“a”到“z”之间的所有小写字母。 |
[^m-z] | 负字符集。匹配指定字符集中的所有非字符。例如,“[^m-z]”匹配“m”和“z”之间的所有非字符。 |
\b | 匹配表示单词的边界,即单词与空格之间的位置。例如,“er\b”匹配“lever”中的“er”,但不匹配“verbe”中的“er”。 |
\B | 匹配不代表单词的边界。“en*t\B”匹配“bien entendu”中的“ent”。 |
\d | 表示一个数字字符。等同于 [0-9]。 |
\D | 匹配不代表数字的字符。等同于 [^0-9]。 |
\f | 对应于换行符。 |
\n | 表示换行符。 |
\r | 对应回车符。 |
\s | 表示任何空白字符,包括空格、制表符、分页符等。等同于“[ \f\n\r\t\v]”。 |
\S | 匹配任何非空白字符。等同于“[^ \f\n\r\t\v]”。 |
\t | 匹配制表符。 |
\v | 匹配垂直制表符。 |
\w | 匹配任何代表单词且包含下划线的字符。等同于“[A-Za-z0-9_]”。 |
\W | 匹配任何不代表单词的字符。等同于“[^A-Za-z0-9_]”。 |
\num | 匹配 num,其中 num 是一个正整数。指代存储的匹配项。例如,"(.)\1" 匹配两个连续的相同字符。 |
\n | 对应于 n,其中 n 是一个八进制转义值。八进制转义值必须包含 1、2 或 3 个数字。例如,“\11”和“\011”都对应于一个制表符。 "\0011" 等同于 "\001" & "1"。八进制转义值不得超过 256。如果超过,则表达式中仅考虑前两位数字。允许在正则表达式中使用 ASCII 代码。 |
\xn | 等同于 n,其中 n 是一个十六进制转义值。 十六进制转义值必须包含两个数字。例如,“\x41”对应“A”。“\x041”等同于“\x04”和“1”。允许在正则表达式中使用代码 ASCII。 |
模板中的一个元素可以出现一次或多次。下面通过几个关于 \d 符号的示例来说明,该符号代表 1 个数字:
模式 | 含义 |
\d | 一个数字 |
\d? | 0 或 1 个数字 |
\d* | 0 个或更多数字 |
\d+ | 1 个或多个数字 |
\d{2} | 2个数字 |
\d{3,} | 至少 3 个数字 |
\d{5,7} | 5 到 7 位数字 |
现在设想一个能够描述字符串预期格式的模式:
要查找的字符串 | 模式 |
日期格式为 dd/mm/yy | \d{2}/\d{2}/\d{2} |
时长格式为 hh:mm:ss | \d{2}:\d{2}:\d{2} |
一个无符号整数 | \d+ |
一个可能为空的空格序列 | \s* |
一个无符号整数,其前后可能有空格 | \s*\d+\s* |
一个可能带符号的整数,其前后可能有空格 | \s*[+|-]?\s*\d+\s* |
一个无符号实数,其前后可能有空格 | \s*\d+(.\d*)?\s* |
一个可能带符号且前后带有空格的实数 | \s*[+-]?\s*\d+(.\d*)?\s* |
包含单词“just”的字符串 | \bjuste\b |
可以指定在字符串中搜索模式的位置:
模式 | 含义 |
^模式 | 模式位于字符串开头 |
模式$ | 模式结束字符串 |
^模式$ | 模式开头和结尾 |
模式 | 从字符串开头开始,在整个字符串中搜索该模式。 |
要搜索的字符串 | 模式 |
以感叹号结尾的字符串 | !$ |
以句点结尾的字符串 | \.$ |
以 // 序列开头的字符串 | ^// |
仅包含一个单词(前后可能有空格)的字符串 | ^\s*\w+\s*$ |
一个字符串,包含两个单词,前后可能有空格 | ^\s*\w+\s*\w+\s*$ |
包含单词 secret 的字符串 | \bsecret\b |
模式的子集可以被“提取”。因此,我们不仅可以验证一个字符串是否符合特定模式,还可以从该字符串中提取那些用圆括号括起的、与模式子集对应的元素。 例如,若要解析包含日期格式 dd/mm/yy 的字符串,并提取其中的 dd、mm、yy 元素,则应使用模式 (\d\d)/(\d\d)/(\d\d)。
脚本结果
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_11.py
Résultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)
Résultats(12 34,^.*?(\d+).*?$)
('12',)
Résultats(abcd,^.*?(\d+).*?$)
La chaîne [abcd] ne correspond pas au modèle [^.*?(\d+).*?$]
Résultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')
Résultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')
Résultats(abcd,^(.*?)(\d+)(.*?)$)
La chaîne [abcd] ne correspond pas au modèle [^(.*?)(\d+)(.*?)$]
Résultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')
Résultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')
Résultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaîne [5/1/01] ne correspond pas au modèle [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]
Résultats(187.8,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')
Résultats(-0.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')
Résultats(4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')
Résultats(.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')
Résultats(4.,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')
Résultats( + 4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')
Process finished with exit code 0