概述
目录
- 1.模块sys
- 1).介绍
- 1.模块sys中一些重要的函数和变量
- 2.变量sys.argv
- 3.函数sys.exit
- 4.映射sys.modules
- 5.变量sys.path
- 6.变量sys.platform
- 7.变量sys.stdin、sys.stdout、sys.stderr
- 2).例子
- 2.模块os
- 1).介绍
- 1.描述几个最有用的函数和变量
- 2.映射os.environ
- 3.函数os.system
- 4.变量os.sep
- 5.变量os.linesep
- 6.函数urandom
- 2).例子
- 更佳的解决方案
- 3.模块fileinput
- 1).介绍
- 1.一些重要的函数
- 2.函数fileinput.input
- 3.函数fileinput.filename
- 4.函数fileinput.lineno
- 5.函数fileinput.filelineno
- 6.函数fileinput.isfirstline
- 7.函数fileinput.isstdin
- 8.函数fileinput.nextfile
- 9.函数fileinput.close
- 2).示例
- 4.集合,堆,双端队列
- 1).集合
- frozenset类型
- 2).堆
- 1.模块heapq中的一些重要函数
- 2.函数heappush
- 3.函数heappop
- 4.函数heapify
- 5.函数heapreplace
- 6函数nlargest(n,iter)和函数nsmallest(n,iter)
- 3).双端队列
- 5.模块time
- 1).介绍
- 1.字段和一些重要函数
- 2.函数time.asctime
- 3.函数time.localtime
- 4.函数time.mktime
- 5.函数time.sleep
- 6.函数time.strptime
- 7.函数time.time
- 6.模块random
- 1).介绍
- 1.一些重要函数
- 2.函数random.random
- 3.函数random.getrandbits
- 4.函数random.uniform
- 5.函数random.randrange
- 6.函数random.choice
- 7.函数random.shuffle
- 8.函数random.sample
- 2).示例
- 7.模块shelve和模块json
- 1).模块shelve
- 简单的数据库
- 8.模块re
- 1).正则表达式
- ❶通配符
- ❷特殊字符的转义
- ❸字符集
- ❹二选一和子模式
- ❺可选模式和重复模式
- ❻字符串的开头和末尾
- 2).模块re
- 1.一些重要函数
- 2.函数re.compile
- 3. 函数re.search
- 4.函数re.match
- 5.函数re.split
- 6.函数re.findall
- 7.函数re.sub
- 8.re.escape
- 3).匹配对象和编组
- 1. re匹配对象的重要方法
- 2.方法group
- 3.方法start
- 4.方法end
- 5.方法span
- 6.示例
- 4).替换中的组号和函数
1.模块sys
1).介绍
模块sys能让你访问和Python解释器紧密相关的变量和函数
1.模块sys中一些重要的函数和变量
2.变量sys.argv
包含传递给Python解释器的参数,其中包括脚本名。
3.函数sys.exit
退出当前程序。你可以向它提供一个整数,指出程序是否成功,这是一种UNIX约定。在大多数情况下,使用该参数的默认值(0,表示成功)即可。也可以向它提供一个字符串,这个字符串将成为错误信息,对用户找出程序终止的原因很有帮助。在这种情况下,程序退出时降显示指定的错误信息以及一个表示失败的编码。
4.映射sys.modules
将模块名映射到模块(仅限于以导入的模块)
5.变量sys.path
它是一个字符串列表,其中的每个字符串都是一个目录名,执行import语句时将在这些目录中查找模块。
6.变量sys.platform
它是一个字符串.试运行解释器的“平台”名称。可能是表示操作系统的名称,也可能是表示其他平台类的名称
7.变量sys.stdin、sys.stdout、sys.stderr
它们是类似于文件的流对象,表示标准的UNIX概念:标准输入、标准输出、标准错误。换而言之,Python从sys.stdin获取输入(例如,用于input中),并将输出打印到sys.stdout。
2).例子
反转并打印命令行参数
#reverseargs.py
import sys
args=sys.argv[1:]
args.reverse()
print(''.join(args))
如你所见,我创建了一个sys.argv的副本。也可以修改sys.argv,一般而言,这样做是不安全的,因为程序的其他部分可能依赖于包含原始参数的sys.argv。另外,跳过了sys.argv的第一个元素,即脚本的名称。使用args.reverse()反转这个列表,但不能打印这个操作的返回值,因为它就地修改列表并返回None。当然了,也有另一种解决方案
#另一种解决方案
print(''.join(reversed(sys.argv[1:])))
#为美化输出,使用了字符串的方法join。假设使用的是bash shell
$ python reverseargs.py this is a test
test a is this
2.模块os
1).介绍
模块os可以让你访问多个操作系统服务。它包含的内容非常多。
1.描述几个最有用的函数和变量
除此之外,os及其子模块os.path还包含多个查看、创建和删除目录文及件的函数,以及一些操作路径的函数。例如:os.path.spilt和os.path.join可以让你在大多数情况下忽略os.pathsep。
2.映射os.environ
包含环境变量。也可以使用它修改环境变量,但并不是所有的平台都支持这样做。要访问环境变量PYTHONPATH,可使用表达式os.environ[‘PYTHONPATH’]
3.函数os.system
用于运行外部程序,还有其他用于执行外部程序的函数,如exec v和popen。前者将推出Python解释器,并将控制权交给被执行的程序。后者则创建一个倒程序的连接.
模块subprocess融合了模块os.sytem以及函数execv和popen的功能。
4.变量os.sep
用于路径名的分隔符。在UNIX以及macOS的命令行Python版本中,标准分隔符为/。在Windows中,标准分隔符为(这种Python语法表示单个反斜杠)。旧式macOS中,标准分隔符为:。可以使用os.pathsep来组合多条路径,就像PYTHONPATH中那样。pathsep用于分隔不同的路径名:在UNIX和macOS中为:,而在Windows中为;。
5.变量os.linesep
用于文本文件中的行分隔符:在UNIX/OSX中为单个换行符(n),在Windows中为回车和换行符(rn)。
6.函数urandom
使用 随系统而异的“真正”(至少是强加密)随机源。如果平台没有提供这样的随机源将引发NotImplementedError异常。
2).例子
启动Web浏览器
命令system可用于执行任何外部程序,这在UNIX等环境中很有用,因为你可以从命令行执行程序(或命令)来列出目录的内容、发送电子邮件等。它还可以用于启动图形用户界面程序,如Web浏览器。在UNIX中,可以像下面这样做(假定/uer/bin/firefox处有浏览器):
os.system('/uer/bin/firefox')
#Windows中,如下操作
os.system(r'C:"Program Files (x86)""Mozilla Firefox"firefox.exe')
注意:这里用引号将Program Files和Mozilla Firefox括起来了。若不这样做,底层shell将受阻于空白处(对于PYTHONPATH中的路径,也必须这样做。)。使用反斜杠的原因是因为Windows shell不能识别斜杠。执行这个命令后,你会发现浏览器试图打开名为Files"Mozilla …(空白后的命令部分)的网站。若你在IDIE中执行这个命令,会出现一个DOS窗口,关闭这个窗口后浏览器才会启动。
Windows特有的函数os.startfile也可以完成这个任务
os.system(r'C:Program Files (x86)Mozilla Firefoxfirefox.exe')
os.system接受一个普通路径,和上面的区别是没有用引号括起Program Files、Mozilla Firefox
更佳的解决方案
就启动Web浏览器而言,更好的方法是使用webbrowser
它包含一个函数——open,让你能够在打开Web浏览器的同时打开指定的URL。
如要让程序在Web浏览器中打开Python网站,可以像下面这样做:
import webbrowser
webbrowser.open('http://www.python.org')
也可以换成https://www.baidu.com,响应更快一些。
3.模块fileinput
1).介绍
模块fileinput能让你轻松地迭代一系列为文本文件中的所有行。
$ python some_script.py file1.txt file2.txt file3.txt
就能够依次迭代文件file1.txt到file3.txt中的行。也可以在UNIX管道中对使用UNIX标准命令cat提供给标准输入(sys.stdin)的行进行迭代。
$ cat file.txt | python some_script.py
若使用模块fileinput,在UNIX管道中使用cat调用脚本的效果将于以命令行参数的方式向脚本提供文件名一样。
1.一些重要的函数
2.函数fileinput.input
它是其中最重要的函数,它返回一个可在一个for循环中进行迭代的对象.若要覆盖默认行为(确定要迭代哪些文件),可以用序列的方式向这个函数提供一个或多个文件名.还可以将参数inplace设置为True(inplace=True),这样就会就地处理.
对于你访问的每一行,都会打印出替代内容,这些内容将写回到当前输出文件中.就地进行处理时,可选参数backup用于给从原始文件创建的备份文件指定扩展名.
3.函数fileinput.filename
返回当前文件(当前处理的行所属文件)的文件名
4.函数fileinput.lineno
返回当前行的编号.这个值是累计的,处理完一个文件接着处理下一个文件时,不会重置行号,而是从前一个文件最后一行的行号加一开始.
5.函数fileinput.filelineno
返回当前行在当前文件中的行号,每处理完一个文件接着处理下一个文件时,将重置这个行号并从一重新开始.
6.函数fileinput.isfirstline
在当前行为当前文件第一行时返回True,否则返回Flase.
7.函数fileinput.isstdin
在当前文件为sys.stdin时返回True,否则返回Flase.
8.函数fileinput.nextfile
关闭当前文件并跳到下一个文件,且计数时忽略跳过的行.
9.函数fileinput.close
关闭整个文件链并结束迭代
2).示例
假设你编写了一个脚本,想给其中的代码行加上行号.
#numberlines.py
import fileinput
for line in fileinput.input(inplace=True):
line=line.rstrip()
num=fileinput.lineno()
print('{:<50}#{:2d}'.format(line,num))
像下面这样运行这个程序,并将其作为参数传入:
$ python numberlines.py numberlines.py
运行结果
#numberlines.py #1
#2
import fileinput #3
#4
for line in fileinput.input(inplace=True): #5
line=line.rstrip() #6
num=fileinput.lineno() #7
print('{:<50}#{:2d}'.format(line,num)) #8
注意到程序本身被修改了,若多运行几次,每行都将包含多个行号.
rstrip是一个字符串方法,它将删除指定字符串右边的空白,并返回结果.
⚠️⚠️⚠️
务必慎用参数inplace,因为会破环文件.在不设置inplace的情况下仔细测试程序,确保程序能够正确运行后再让它修改文件.
4.集合,堆,双端队列
1).集合
之前由模块sets中的Set类实现,现在由内置类set实现.这意味着你可以直接创建集合,无需导入模块sets
print(set(range(6)))
#运行结果
{0, 1, 2, 3, 4, 5}
也可以使用序列(或其他可迭代对象)来创建集合,也可使用花括号显示地指定.不能仅使用花括号来创建空集合,因为这将创建一个空字典.
print(type({}))
#运行结果
<class 'dict'>
集合主要用于成员资格检查,将忽略重复元素
print({0,1,2,3,4,2,2,2,2,2,5,67,86,5,})
#运行结果
{0, 1, 2, 3, 4, 5, 67, 86}
和字典一样,集合中元素的排列顺序是不确定的.
集合可以像数学中那样,进行各种程序版的各种标准集合操作.
例如:计算两个集合的并集,可使用集合调用方法union,或使用按位或运算符|.
a={1,2,3}
b={2,3,4}
print(a.union(b)) #求并集
{1, 2, 3, 4}
print(a|b)
{1, 2, 3, 4}
其他方法、运算符
c=a&b
print(c.issubset(a)) #判断集合c内元素是否都在集合a中
True
print(c<=a)
True
print(c>=a)
False
print(a.intersection(b)) #求交集
{2, 3}
print(a&b)
{2, 3}
print(a.difference(b)) #求差集
{1}
print(a-b)
{1}
print(a.symmetric_difference(b)) #求两个集合不相同的部分
{1, 4}
print(a^b)
{1, 4}
print(a.copy()) #复制集合a
{1, 2, 3}
print(a.copy() is a)
False
因为集合是可变的,所以不能作为字典中的键.集合只能包含不可变的值,因此不能包含其他集合.
frozenset类型
它表示不可变的(可散列)的集合.
a=set()
b=set()
print(a.add(frozenset(b)))
print(a.add(b))
#运行结果
None
Traceback (most recent call last):
File line 4, in <module>
print(a.add(b))
TypeError: unhashable type: 'set'
构造函数frozenset创建给定集合的副本.在需要将集合另一个集合的成员或字典中的键时,frozenset很有用.
2).堆
堆是一种数据结构。它是一种优先队列.让你能够让你以任意顺序添加对象,并随时找出并删除最小的元素.
Python没有独立的堆类型,只有一个模块——heapq
1.模块heapq中的一些重要函数
前四个和堆操作有关
2.函数heappush
用于在堆中添加元素.它只能用于各种堆函数创建的函数.
from heapq import*
from random import shuffle
data=list(range(10))
shuffle(data)
heap=[]
for n in data:
heappush(heap,n)
print(heap)
heappush(heap,0.5)
print(heap)
#运算结果
[0, 2, 1, 6, 3, 5, 7, 9, 8, 4]
[0, 0.5, 1, 6, 2, 5, 7, 9, 8, 4, 3]
元素的排列顺序遵循位置a处的元素大于位置a//2(相除之后,向下取整.如5//2=2, 5/2=2.5)处的元素.这是底层堆算法的基础,称为堆特征.
3.函数heappop
弹出最小的元素(总是位于索引0处),并确保剩余元素中最小的位于索引0处(保持堆特征).
print(heappop(heap))
print(heappop(heap))
print(heappop(heap))
print(heap)
#运行结果
0
0.5
1
[2, 3, 6, 4, 8, 9, 7, 5]
4.函数heapify
通过执行尽可能少的移位操作将列表变成合法的堆.若你的堆并不是使用heappush创建的,应在使用heappush和heappop之前使用这个函数.
heap=[5,6,9,0,1,2,8,4,3]
heapify(heap)
print(heap)
#运行结果
[0, 1, 2, 3, 5, 9, 8, 4, 6]
5.函数heapreplace
从堆中弹出最小的元素,再压入一个新元素.相比于依次执行函数heappop和函数heappush,效率更高.
from heapq import*
from random import shuffle
data=list(range(10))
shuffle(data)
heap=[]
for n in data:
heappush(heap,n)
print(heap)
print(heapreplace(heap,0.5))
print(heap)
print(heapreplace(heap,10))
print(heap)
#运算结果
[0, 2, 1, 3, 4, 6, 7, 5, 8, 9]
0
[0.5, 2, 1, 3, 4, 6, 7, 5, 8, 9]
0.5
[1, 2, 6, 3, 4, 10, 7, 5, 8, 9]
6函数nlargest(n,iter)和函数nsmallest(n,iter)
分别用于找出可迭代对象iter中最大和最小的n个元素.
3).双端队列
在需要按添加元素的顺序进行删除时,双端队列很有用.在模块collections中,包含类型deque以及其他几个集合(collection)类型.
和集合(set)一样,双端队列也是从可迭代对象创建的.
from collections import deque
Q=deque(range(6))
Q.append(6)
Q.appendleft(7)
print(Q)
print(Q.pop())
print(Q.popleft())
Q.rotate(4)
print(Q)
Q.rotate(-1)
print(Q)
#运行结果
deque([7, 0, 1, 2, 3, 4, 5, 6])
6
7
deque([2, 3, 4, 5, 0, 1])
deque([3, 4, 5, 0, 1, 2])
双端队列支持在队首(左端)高效的附加和弹出元素,而列表无法这样做.因此显得双端队列很有用.除此之外,还可高效的旋转元素(将元素向左或向右移,并在到达一端时环绕到另一端).
双端队列还包含方法extend和extendleft.
其中extend类似于相应的列表的方法,而extendleft类似于appendleft.
⚠️⚠️⚠️
用于extendleft的可迭代对象中的元素将按相反的顺序出现在双端队列中.
5.模块time
1).介绍
它包含用于获取时间、操作时间和日期的、从字符串中读取日期、将日期格式化为字符串的函数.
1.字段和一些重要函数
秒的的取值范围是0~61是考虑到闰一秒和闰两秒的情况.夏令时数字是一个布尔值,如果你使用-1,那么mktime可能得到正确的值
2.函数time.asctime
将当前时间转化为字符串.
>>>time.asctime()
>'Mon Jul 18 14:14:14 2022'
若不想使用当前时间,可向它提供一个日期元组.
3.函数time.localtime
将一个实数转化为日期元组(本地时间),若要转化为国际时间,应使用gmtime.
4.函数time.mktime
将日期元组转化为从新纪元后的秒数.
5.函数time.sleep
让解释器等待指定的秒数.
6.函数time.strptime
将一个字符串(格式和asctime所返回的字符串的格式相同)转化为日期元组
7.函数time.time
返回当前的国际标准时间.
6.模块random
1).介绍
包含生成伪随机数的函数,有助于编写模拟程序或随机输出的函数.如果想要真正的随机输出,使用模块os中的函数urandom.
1.一些重要函数
2.函数random.random
最基本的随机函数之一,它返回一个0~1(含)的伪随机数
3.函数random.getrandbits
以一个整数的方式返回指定数量的二进制位。
4.函数random.uniform
向它提供了两个数字参数a和b时,它返回一个a~b(含)的随机(均匀分布的)实数。例如,如果你需要一个随机角度,可使用uniform(0,360)。
5.函数random.randrange
生成随机整数的标准函数。为指定这个随机整数所在的范围,你可像调用range那样给这个函数提供参数。例如,要生成一个1~10(含)的随机整数,可使用randrange(1,11)或randrange(10)+1。要生成一个小于20的随机正奇数,可使用randrange(1,20,2)。
6.函数random.choice
从给定序列中随机(均匀)地选择一个元素。
7.函数random.shuffle
随机地打乱一个可变序列中的元素,并确保每种可能的排列顺序出现的概率相同。
8.函数random.sample
从给定序列中随机(均匀)地选择指定数量的元素,并确保所选择元素的值各不相同。
2).示例
1
from random import*
from time import*
date1=(2022,9,18,5,20,13,-1,-1,-1)
time1=mktime(date1)
date2=(2023,1,13,14,5,20,-1,-1,-1)
time2=mktime(date2)
random_time=uniform(time1,time2)
print(asctime(localtime(random_time)))
#运算结果
Sun Dec 18 02:51:14 2022
2
from random import randrange
num=int(input('How many dice?'))
sides=int(input('How many sides per die?'))
sum=0
for i in range(num): sum+=randrange(sides)+1
print('The result is',sum)
若在脚本文件中运行,会发现下面的内容:
How many dice? 3
How many sides per die? 6
The result is 10
假如你创建了一个文件,每一行都包含一种情况(fortune),可使用模块fileinput将这些情况放在列表中,再随机选择一种.
# fortune.py
import fileinput,random
fortunes=list(fileinput.input())
print(random.choice(fortunes))
在UNIX和macOS中,可以使用标准字典文件/usr/share/dict/words来测试程序,将获得一个随机的单词.
$ python fortune.py /usr/share/dict/words
dodge
7.模块shelve和模块json
1).模块shelve
import shelve
S=shelve.open('test.dat')
S['x']=['a','b','c']
S['x'].append('d')
print(S['x'])
#运行结果
['a', 'b', 'c']
d在哪里?
当你检查shelf对象时,将使用存储版重建该对象.当你把一个元素赋给键时,该元素会被存储.上述示例发生事情如下:
1.列表[‘a’,‘b’,‘c’]被存储在s的‘x’键下
2.获取存储的表示,并使用它创建一个新列表,再将‘d’附加到这个列表的末尾,但是修改后的列表没有被保存!
3.获取原来的列表.
要想正确修改模块shelve存储的对象,必须将获取的副本(新建列表)赋给一个临时变量,并在修改后再次存储:
import shelve
S=shelve.open('test.dat')
S['x']=['a','b','c']
S['x'].append('d')
print(S['x'])
temp=S['x']
temp.append('d')
S['x']=temp
print(S['x'])
#运行结果
['a', 'b', 'c']
['a', 'b', 'c', 'd']
另一种方法是将函数open的参数writeback设置为True.这样,从shelf对象读取或赋给它的所有数据结构都将保存到内存中,并等到你关闭shelf对象时才将它们写入磁盘.这时必须确保处理完毕后将shelf对象关闭.
简单的数据库
# database.py
import sys, shelve
def store_person(db):
#让用户输入数据并将其存储到shelf对象中
pid = input('Enter unique ID number:')
person={}
person['name']=input('Enter name:')
person['age' ] = input('Enter age:')
person['phone']= input('Enter phone number:')
db[pid] = person
def lookup_person(db):
#让用户输入ID和所需的字段,并从shelf对象中获取相应的数据
pid = input('Enter ID number:')
field = input('What would you like to know? (nane, agc, phone)')
field = field.strip().lower()
print(field.capitalize() + ':',db[pid][field])
def print_help():
print('The available commands are:')
print('store : Stores information about a person')
print('lookup : Looks up a person from ID number')
print('quit : Save changes and exit')
print('?: Prints this message')
def enter_command():
cmd =input('Enter command (? for help):')
cmd = cmd.strip().lower()
return cmd
def main():
database = shelve.open('C:\database.dat')#你可能想修改这个名称
try:
while True:
cnd = enter_command()
if cmd =='store':
store_person(database)
elif cmd =='lookup':
lookup_person(database)
elif cmd_=='?':
print_help()
elif cmd =='quit':
return
finally:
database.close()
if __name__=='__main__':main()
#数据交换
Enter command(? for help):?
The available commands are:
store:Storesinformation about a person
lookup: Looks up a personfrom ID number
quit : Save changes and exit
1 ··Printsthis message
Enter command(? for help):store
Enter unique ID number:001
Enter name:Mr. Gumby
Enter age:42
Enter phone number:555-1234
Enter command(? for help):lookup
Enter ID number:001
What would you like to know?(name, age, phone) phonePhone:555-1234
Enter command (? for help):quit
这个交互过程并不是很好。我原本可以使用普通字典(而不是shelf对象)来完成这个任务。退出这个程序后,再次运行情况:
Enter command (? for help):lookup
Enter ID number:001
What would you like to know? (name, age, phone) name
Name: Mr. Gumby
Enter command (? for help):quit
如你所见,这个程序读取前面运行它时创建的文件,该文件依然包含Mr.Gumby!请随便实验这个程序.
提示 如果要以这样的格式保存数据,也就是让使用其他语言编写的程序能够轻松地读取它们,可考虑使用JSON格式。Python标准库提供了用于处理JSON字符串(在这种字符串和Python值之间进行转换)的模块json。
8.模块re
1).正则表达式
正则表达式是可匹配文本片段的模ernizjwj/式.最简单的正则表达式是普通字符串.
❶通配符
正则字符串可以和多个字符串匹配,可以通过特殊字符来创建它.
如:'. ython'
不仅和字符串'python'
、字符串'jython'
,还和'qython'
、'+ython'
、' ython'
等字符串匹配.但不和'cpythpn'
、'ython'
等字符串匹配
句点能和除换行符以外的任意字符匹配.所以被称为 通配符
❷特殊字符的转义
普通字符只与自己匹配,和特殊字符的情况完全不同.
如:假设要匹配字符串'python.org'
,可以直接使用模式'python.org'
,也可以对其进行转义:在它前面加上一个反斜杠().模式'python\.org'
只与 'python.org'
匹配.
为什么是'python\.org'
而不是'python.org'
?
这里包含两层转义:一次是解释器执行的转义,一次是模块re执行的转义.在有些情况下也可以使用单个反斜杠,让解释器对其进行转义,但最好不这样做.不喜欢这样做,可以使用原始字符串r'python.org'
❸字符集
匹配字符很有用,但有时需要更细致的掌控.所以可以用方括号将一个子串括起,创建一个字符集.这样的字符集与其包含的字符都匹配,如’p]ython'
与‘python'
和'ychon'
都匹配,但不与其他字符串匹配。
还可以使用范围,如'[a-z]'
与a~z的任何字母都匹配.
还可以组合多个访问,方法是依次列出它们,如‘[a-zA-20-9]‘
与大写字母、小写字母和数字都匹配。但是,字符集只能匹配一个字符。
要指定排除字符集,可在开头添加一个^字符,如'[^abc]'
与除a、b和c外的其他任何字符都匹配。
字符集中的特殊字符
一般来说:对于句点、星号和问号等特殊字符,要在模式中将其用作字面字符而不是正则表达式运算符,必须使用反斜杠对其进行转义。在字符集中,通常不需要对这些字符进行转义,但进行转义也是完全可以的。
但是,要遵循如下规则:
1.脱字符(^)位于字符集开头时,除非要将其用作排除运算符,否则必须对其进行转义。除非有意为之,否则不要将其放在字符集开头。
2.对于右方括号()和连字符(-),要么将其放在字符集开头,要么使用反斜杠对其进行转义。也可以将连字符放在字符集末尾。
❹二选一和子模式
需要以不同的方式处理每个字符时,字符集很好用,但如果只想匹配字符串'python'
和'perl'
,该如何办?使用字符集或通配符无法指定这样的模式.必须使用表示二选一的特殊字符:管道字符(|)。
所需的模式为‘python|perl'
。但是,有时你并不想将二选一运算符用于整个模式,而是想将其用于模式的一部分。为此可将这部分(子模式)放在圆括号内。
对于前面的示例,可重写为'p(ython|erl)'
。
注意,单个字符也可以称为子模式。
❺可选模式和重复模式
通过在子模式后面加上问号,可将其指定为可选的,即可包含可不包含。如,下面这个模式:
r'(http://)7(www.) python.org
只与下面这些字符串匹配:
'http://www.python.org
"http://python.org
‘www.python.org
'python.org
对于这个示例,需要注意如下几点:
1.对句点进行了转义,防止它充当通配符。
2.为减少所需的反斜杠数量,使用了原始字符串。
3.每个可选的子模式都放在圆括号内。
4.每个可选的子模式都可以出现,也可以不出现。
5.问号表示可选的子模式可出现一次,也可不出现。
还有其他几个运算符用于表示子模式可重复多次。
1.(pattern)*:pattern
可重复0、1或多次。
2.(pattern)+:pattern
可重复1或多次。
3.(pattern)fm,n):
模式可重复m-n次。
例:r'w*.python.org'
与’www.python.org’、
.python.org’‘、
‘ww.python.org’和
’wwwwww.python.org’匹配。
r’w+.python.org’与
‘w.python.org’匹配,但与
’.python.otg’不匹配,
r’w(3,4.python.org’只与
’www.python.org’和
’www.python.org’`匹配。
⚠️⚠️⚠️
在这里,术语匹配指的是与整个字符串匹配,而函数match只要求模式与字符串开头匹配。
❻字符串的开头和末尾
到目前为止,讨论的都是模式是否与整个字符串匹配,但也可查找与模式匹配的子串,如字符串‘wid.python.org'
中的子串‘wow’
与模式'w+'
匹配。像这样查找字符串时,有时在整个字符串开头或末尾查找很有用。如果你想确定字符串的开头是否与模式’ht+p’匹配,为此可使用脱字符(n’)来指出这一点。如:‘Aht+p'
与'http://python.org'
和'htttttp://python.org
匹配,但与’wow.http,org'
不匹配。
要指定字符串末尾,可使用美元符号($)。
2).模块re
1.一些重要函数
2.函数re.compile
使用字符串表示的正则表达式转换为模式对象,以提高匹配效率。调用search、match等函数时,若提供的是用字符串表示的正则表达式,必须在内部将它们转换为模式对象。
使用函数compile对正则表达式进行转换后,每次使用它时都无须再进行转换。
模式对象也有搜索/匹配方法,因此re.search(pat,string)(其中pat是一个使用字符串表示的正则表达式)等价于pat.search(string)(其中pat是使用compile创建的模式对象)。编译后的正则表达式对象也可用于模块re中的普通函数中。
3. 函数re.search
在给定字符串中查找第一个与指定正则表达式匹配的子串。若找到这样的子串,将返回MatchObject(结果为真),否则返回None(结果为假)。
鉴于返回值的这种特征,可在条件语句中使用如下所示的函数:
if re.search(pat, string):
print('Found it!')
如果需要获悉有关匹配的子串的详细信息,可查看返回的Matchobject。
4.函数re.match
在给定字符串开头查找与正则表达式匹配的子串,因此re.match(‘p’,‘python’)返回真(MatchObject),而re.match(‘p’, ‘ww.python.org’)返回假(None)。
⚠️注意⚠️
函数match在模式与字符串开头匹配时就返回True,而不要求模式与整个字符串匹配。若要求与整个字符串匹配,需要在模式末尾加上一个美元符号。美元符号要求与字符串
末尾匹配,从而将匹配检查延伸到整个字符串。
5.函数re.split
根据与模式匹配的子串来分割字符串。类似于字符串方法split,但使用正则表达式来指定分隔符,而不是指定固定的分隔符。
如:使用字符串方法split时,可以把字符串’,‘
当作分隔符来分割字符串,但在使用re.split时,可以空格和逗号作为分隔符来分割字符串。
>>>some text ='alpha, beta,,gamma delta'
>>> re.split('[, ]+', some text)
['alpha', 'beta', 'gamma','delta']
注意
若模式包含圆括号,将在分割得到的子串之间插入括号中的内容。例如,re.split(o(g)‘foobat’)的结果为[‘f’, ‘o’, "bar’]。
从这个示例可知,返回值为子串列表。参数maxsplit指定最多分制多少次。
>>> re.split('[, ]+', some_text, maxsplit=2)
delta']
gamma
['alpha’, 'beta' ]+', soe_text, maxsplit=1)
>>> re.split('[,
['alpha', 'beta,,,gamma delta']
6.函数re.findall
返回一个列表,其中包含所有与给定模式匹配的子串。
例如,要找出字符非包含的所有单词,像下面这样做:
>>> pat ='[a-zA-Z]+'
>>> text = ""Hm.. Erx -- are you sure?" he said, sounding insecure.’
>>> re.findall(pat,text)
['Hn','Ert', "are', "you', 'sure', 'he', 'said', 'sounding', "insecure']
要查找所有的标点符号,可以像下面这样做:
>>> pat =r'[.?-", ]+'
>>> re.findall(pat, text)
['"’ ,'?"' ']
⚠️这里对连字符(-)进行了转义,所以Python不会认为它是用来指定字符范围的(如a-z)。
7.函数re.sub
从左往右将与模式匹配的子串替换为指定内容。
示例:
>>> pat ='(name)'
>>> text ='Dear fname...
>>> re.sub(pat, 'Mr. Gumby',text)
'Dear Mr. Gumby...'
8.re.escape
它是一个工具函数,用于对字符串中所有可能被视为正则表达式运算符的字符进行转义。
使用这个函数的情况有:字符串很长,其中包含大量特殊字符,而你不想输入大量的反斜杠;你从用户那里获取了一个字符串(例如,通过函数input),想将其用于正则表达式中。工作原理:
>>> re.escape('www.python.org')
'wwwl.pythonV.org
>>> re.escape('But where is the ambiguity?')
‘But wherel isl thell ambiguity\?'
注意
有些函数接受一个名为flags的可选参数。这个参数可用于修改正则注意来达式的解读方式。
3).匹配对象和编组
在模块re中,查找与模式匹配的子串的函数都在找到时返回MatchObject对象。这种对象包含与模式匹配的子串的信息,还包合模式的理部分与子串的哪部分匹民的信息。这些子串部分为编组(group)。
编组就是放在圆括号内的子模式,是根据左边的括号数编号的,其中编组0指的是整个模式。因此,在下面的模式中:
There (was a (wee) (cooper)) who (lived in Fyfe)"
包含如下编组:
o There was a wee cooper who lived in Fyfe
1 was a wee cooper
2 wee
3 cooper
4 lived in Fyfe
通常,编组包含诸如通配符和重复运算符等特殊字符,因此你可能想知道与给定编组匹配的内容。
例如,在下面的模式中:
r'ww.(.+).com$"
编组0包含整个字符串,而编组1包含‘ww.'和".com’之间的内容。通过创建类似于这样的模式,可提取字符串中你感兴趣的部分。
1. re匹配对象的重要方法
2.方法group
返回与模式中给定编组匹配的子串。
若没有指定编组号,则默认为0。如果只指定了一个编组号(或使用默认值0),将只返回一个字符串;否则返回一个元组,其中包含与给定编组匹配的子串。
注意
除编组0外,最多还可以有99个编组,编号为1-99。
3.方法start
返回与给定编组(默认为0.即整个模式)匹配的子串的起始索引。
4.方法end
类似于start,但返回终止时索引加1
5.方法span
返回一个元组,其中包含与给定编组(默认为0,即整个模式)匹配的子串的起始索引和终止索引。
6.示例
工作原理:
>> m = re.natch(T'www.(.")..(3),ww.python.org')
>>> m.group(1)
'python'
>>> m.start(1)
4
>>> m.end(1)
10
>>> m.span(1)
(4,10)
4).替换中的组号和函数
为利用re.sub的强大功能,最简单的方式是在替代字符串中使用组号。在替换字符串中,所有类似于“n”的转义序列都将被替换为与模式中编组n匹配的字符串。
例如,假设要将'*something*'
替换为'<em>something</em'
,前者是在纯文本文档中表示出的普通方式,而后者是相应的HTML代码(用于网页中)。
先创建一个正则表达式:
>>> emphasis_pattern = 工'*([*]+)*·
要让正则表达式更容易理解,一种办法是在调用模块re中的函数时使用标志VERBOSE。这让你能够在模式中添加空白(空格、制表符、换行符等),而re将忽略它们——除非将它
放在字符类中或使用反斜杠对其进行转义。
在这样的正则表达式中,还可以添加注释
下述代码创建的模式对象与emphasis_pattern等价,但使用了VERBOSE标志:
>>> emphasis_pattern = re.compile(r'''
...* #起始突出标志———个星号
...( #与要突出的内容匹配的编组的起始位置
...[^*]+ #与除星号外的其他字符都匹配
...) #编组到此结束
... * #结束突出标志
... ''',re.VERBOSE)
...
创建模式后,就可使用re.sub来完成所需的替换了。
>>> re.sub(emphasis pattern, r'cem>1</em>’, ‘Hello, *world*!')
'Hello, <emoworldk/em>!'
如你所见,成功将纯文本转换成了HTML代码。
可以通过将函教作为替换内容,执行更复杂的替换。这个函数将MatchObject作为唯一的参数,它返回的字符串将用作替换内容。换而言之,可以对匹配的字符串做任何处理,并通过细致的处理来生成替换的内容。
最后
以上就是包容自行车为你收集整理的Python标准库:一些受欢迎的模块的全部内容,希望文章能够帮你解决Python标准库:一些受欢迎的模块所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复