Python标准库:一些受欢迎的模块

目录

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中为回车和换行符(\r\n)。

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 Firefox\firefox.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')
'www\l.python\V.org
>>> re.escape('But where is the ambiguity?')
‘But\ where\l is\l 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作为唯一的参数,它返回的字符串将用作替换内容。换而言之,可以对匹配的字符串做任何处理,并通过细致的处理来生成替换的内容。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值