Py学习  »  Python

python办公自动化,在EXCEL办公软件中的应用

Python初级入门到精通 • 4 天前 • 45 次点击  

python办公自动化(入门)

open()函数

在python中使用操作文件之前,需要使用open()打开文件,其会返回一个文件对象。


下面是open函数的参数列表:


open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)

file:要创建或者打开的文件。通常为:文件路径/文件名.文件格式


mode:可选参数,指定文件的打开模式,默认为只读的方式打开


buffering:可选参数,用于设置缓冲策略。具体操作在进阶里面说


encoding:可选参数,用于解码或编码的编码名称文件


errors:可选参数,errors是一个可选字符串,用于指定如何处理编码错误。这个参数不应该在二进制模式下使用


newline:可选参数,控制通用换行符的工作方式


closefd:默认值值为True,如果closefd为False,底层文件描述符将保持打开状态当文件关闭时。当给定了文件名时,这就不起作用了并且在这种情况下必须为真


文件的操作模式(mode参数)有如下几种:


操作模式 具体含义

r读取 (默认)

w写入(会先截断之前的内容)

x写入,如果文件已经存在会产生异常

a追加,将内容写入到已有文件的末尾

b二进制模式

t文本模式(默认)

+更新(既可以读又可以写)

这里我们只需要先了解file、mode、encoding这三个参数


读取文件内容

致橡树.txt 文档


# 返回一个文件对象

file = open(file ='致橡树.txt', mode ='r', encoding ='utf-8')


# 读取所有内容

print(file.read())  


# 切记,每次打开文件之后一定要关闭文件,不然文件会一直占用缓存

file.close()

'r’以只读的方式打开,同时选取utf-8作为文件的编码方式(我的编译器编码方式为utf-8,而致橡树.txt文件的编码方式为gbk,所以需要把文档的编码改为utf-8)


如何查看编译器编码:


import sys


print(sys.getdefaultencoding())  # 查看文件编码

这里有一个问题,就是如果在文件关闭之前,前面的代码出现错误,从而导致无法执行文件关闭的语句,这样怎么办呢?


这里我们可以使用一个异常处理语句try-finally,无论try语句里面的内容是否出现异常,始终都会执行finally语句块里面的内容。


代码如下:


# 返回一个文件对象

file = open(file ='致橡树.txt', mode ='r', encoding ='utf-8')


try:

    # 读取所有内容

    print(file.read())  

finally:

    # 关闭文件

    file.close()

    print('关闭文件成功')

以后我们都将使用上面这个格式去操作文件。


当一个文件很大时,这里将耗费很多时间和缓存,我们可以分批次读取


# 返回一个文件对象

file = open(file ='致橡树.txt', mode ='r', encoding ='utf-8')


try:

    # 一次只读32个字节,读不到数据则返回None

    data = file.read(32)

    while data:

        print(data, end = '')

        data = file.read(32)  

finally:

    # 关闭文件

    file.close()

    print('关闭文件成功')

写入内容

如果要向文件中写入内容,我们需要将文件的打开模式改为a或者w


这里我们打开一个新的空白文件(文件不存在就在当前路径下创建一个新文档)


这里我们文件打开模型选择为w,为只读模式,我不能对其进行读操作。


# 打开 小雨康桥的诗.txt 文件

file = open('小雨康桥的诗.txt', mode = 'w', encoding = 'utf-8')


try:

    # 写入内容

    file.write('我只想做燕子\n')

    file.write('只需简单思想\n')

    file.write('只求风中流浪\n')

    file.write('我想作树\n')

    file.write('不想长五脏六腑\n')

    file.write('不会肝肠寸断\n')

finally:

    # 关闭文件

    file.close()

    print('关闭文件成功')

如果我们还行在文件后面继续写入文件,我们可以进行如下操作


# 打开 小雨康桥的诗.txt 文件  将文件操作模式设置为a

file = open('小雨康桥的诗.txt', mode = 'a', encoding = 'utf-8')


try:

    # 写入内容

    file.write('我做不成燕子\n')

    file.write('所以我飞不过感情的墙\n')

    file.write('我做不成树\n')

    file.write('因此也撑不破伤心的网\n')

finally:

    # 关闭文件

    file.close()

    print('关闭文件成功')

读写二进制文件

先给大家介绍一个函数seek()。我们可以使用它移动文件指针到指定位置,然后进行读写。


seek(移动字节数,移动模式):

移动模式有三种,如下:

0:默认的模式,以文件开头为初始点移动移动指针;

1:以当前指针所在位置为初始点移动指针;

2:以文件末尾为初始位置移动指针;

强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用


实例:


file = open('小雨康桥的诗.txt', mode = 'w', encoding = 'utf-8')

try:

    # 打印当前文件指针的位置

    print(file.tell())  # 200

    # 将文件指针移到开头

    file.seek(0, 0)

    print(file.tell())  # 0

    # 将文件指针移到第八个字节

    file.seek(8, 0)  

    print(file.tell())  # 8

finally:

    file.close()


这里我们文件的操作模式为w,所以不能使用seek(n,1) 、seek(n, 2) (n表示移动字节数)


以二进制形式打开文件,以图片为例,该图片为一个截图


# 导入模块,模块作用如下

from io import SEEK_END, SEEK_SET


# 读取一个图片,以二进制的模打开

file = open(file = 'image.jpg', mode = 'rb')


# 移动文件指针至文件末尾,获取文件长度

file.seek(0, SEEK_END)


# 通过tell方法获取文件指针移动的字节数,这个字节数就是文件的大小

print(file.tell())


# 将文件指针移动到最初的位置

file.seek(0, SEEK_SET)


try:

    data = file.read(512)

    while data:

        print(data, end = '')

        data = file.read()

finally:

    file.close()

    print('关闭文件')

上下文语法

对于open函数,我们还可以用with上下文语法,使用with上下文语法会在结束文件操作之后,会自动保存文件,这样我们就不需要再写finally语句在执行close方法了,让代码变得更简洁。不过并不是所有的对象都可以使用with上下文语法,必须符合上下文管理器协议的对象(有__enter__和__exit__魔术方法)才可以使用。


实例:


# 读文件

with open('小雨康桥的诗.txt', 'r', encoding = 'utf-8-sig') as file:

    # 输出文件内容

    print(file.read())


# 写文件

with open('小雨康桥的诗.txt', 'a', encoding = 'utf-8-sig') as file2:

    # 写入内容

    file2.write('我做不成燕子\n')

    file2.write('所以我飞不过感情的墙\n')

    file2.write('我做不成树\n')

    file2.write('因此也撑不破伤心的网\n')

读写CSV文件

CSV(Comma Separated Values)全称逗号分隔值文件。接下来将使用python对CSV文件进行操作。这里我们需要导入python中的csv模块。


csv这里我们主要介绍两个方法,


csv.reader:返回一个遍历 CSV 文件各行的读取对象(已经读取文件中的所有数据)


csv.writer:将数据写入CSV的写入对象


读取csv文件

import csv


with open('2018年北京积分落户数据2.csv', encoding = 'gb18030') as file:

    # 每次读取文件的一行

    content = file.readline()

    while content:

        # 对读取的数据进行处理,将换行符\n去掉,并且用逗号分隔

        values = content.replace('\n', '').split(',')

        print(values)

        # 读取下一行数据

        content = file.readline()

还可以通过delimiter、quotechar参数来指定分隔符(默认是英文的逗号)、包围值的字符(默认是英文双引号)。其中,包围值的字符主要用于当字段中有特殊符号时,通过添加包围值的字符可以避免二义性。


with open('2018年北京积分落户数据2.csv', encoding = 'gb18030') as file:

    # delimiter:设置分隔符(默认是英文的逗号)

    # quotechar:包裹字符串符号(默认是英文双引号)

    reader = csv.reader(file, delimiter = '#', quotechar = '@')

    for row in reader:

        print(row)

将数据写入csv文件中

import csv

import random


with open('成绩.csv', 'w', encoding = 'utf-8-sig', newline = "") as file:

    writer = csv.writer(file)

    

    # 在文件中写入内容

    writer.writerow(['姓名', '语文成绩', '数学成绩', '英语成绩'])

    names = ['小明', '大毛', '二毛']

    

    # 循环遍历,随机生成三人的各科成绩

    for i in range(3):

        subject1 = random.randrange(50, 101)

        subject2 = random.randrange(60, 101)

        subject3 = random.randrange(40, 101)

        # 写入文件

        writer.writerow([names[i], subject1, subject2, subject3])

读写Excel文件

读写Excel文件,我们需要使用一些python的第三方库:


xlrd / xlwt :读取 / 写入,二者兼容低版本的Excel文件(后缀名为xls)


xlutils:支持同时对Excel文件进行读操作和写入操作


openpyxl:获取Excel对象,兼容高版本的Excel文件(后缀名为xlsx)


读取Excel文件

import xlrd


# 每个Excel文件都是一个工作簿(workbook),每个工作簿包含1个或1个以上的工作表(sheet)

# 获取工作簿

wb = xlrd.open_workbook('阿里巴巴2020年股票数据.xls')

print(type(wb))


# 获取所有工作表的名字

print(wb.sheet_names())


# 获取指定的工作表

sheet = wb.sheet_by_name('股票数据') # 方法一

sheet2 = wb.sheet_by_index(0)# 方法二

print(type(sheet))


# 获取工作表的行数和列数

print(sheet.nrows, sheet.ncols)


# 获取指定的行 

print(sheet.row(0))

print(sheet.row_slice(0, start_colx=0, end_colx=3))


# 获取指定的列 

print(sheet.col(4))

print(sheet.col_slice(4, start_rowx=1, end_rowx=11))


# 获取单元格的数据 

cell = sheet.cell(2, 2)

print(type(cell))

print(cell.value)

遍历整个sheet,根据数据的格式,在遍历的同时对数据进行处理


import xlrd


# 工作簿 ---> 一个Excel文件 ---> Book

wb = xlrd.open_workbook('resources/阿里巴巴2020年股票数据.xls')


# 获取指定的工作表 

sheet = wb.sheet_by_index(0)


# 原工作表中的表头

print(f'交易日期\t\t\t最高价\t\t最低价\t\t开盘价\t\t收盘价\t\t成交量\t\t调整收盘价')


for row in range(1, sheet.nrows):

    for col in range(sheet.ncols):

        value = sheet.cell(row, col).value

        # 第一列是时间数据,对时间进行一个格式化

        if col == 0:

            # year, month, date, *_ = xlrd.xldate_as_tuple(value, 0)

            # print(f'{year}年{month:0>2d}月{date:0>2d}日', end='\t')

            curr_date = xlrd.xldate_as_datetime(value, 0)

            print(curr_date.strftime('%Y年%m月%d日'), end='\t')

         

        elif col == 5:

            print(f'{int(value):<10d}', end='\t')

        else:

            print(f'{value:.4f}', end='\t')

    print()


写Excel文件

import random


import xlwt


names = ['小明', '大毛', '二毛']

scores = [[random.randint(40, 100) for _ in range(3)] for _ in range(3)]


# 创建工作簿对象(Workbook)

wb = xlwt.Workbook()


# 创建工作表对象(Worksheet)

sheet = wb.add_sheet('五年级20班')


# 添加表头数据

titles = ('姓名', '语文成绩', '数学成绩', '英语成绩')

for index, title in enumerate(titles):

    # 在第0行,第index列,添加内容title

    sheet.write(0, index, title)


# 将学生姓名和考试成绩写入单元格

for row in range(len(scores)):

    sheet.write(row + 1, 0, names[row])

    for col in range(len(scores[row])):

        sheet.write(row + 1, col + 1, scores[row][col])

# 保存Excel工作簿

wb.save('考试成绩表.xlsx')

调整单元格样式

我们还可以为单元格设置样式,主要包括字体(Font)、对齐方式(Alignment)、边框(Border)和背景(Background)的设置


import random


import xlwt


names = ['小明', '大毛', '二毛']

scores = [[random.randint(40, 100) for _ in range(3)] for _ in range(3)]


# 创建工作簿对象(Workbook)

wb = xlwt.Workbook()


# 创建工作表对象(Worksheet)

sheet = wb.add_sheet('五年级20班')


# 将表头单元格的背景色修改为蓝色

header_style = xlwt.XFStyle()

pattern = xlwt.Pattern()

pattern.pattern = xlwt.Pattern.SOLID_PATTERN

# 0-黑色、1-白色、2-红色、3-绿色、4-蓝色、5-黄色、6-粉色、7-青色

pattern.pattern_fore_colour = 4

header_style.pattern = pattern


# 为表头设置指定的字体

font = xlwt.Font()

# 字体名称

font.name = '华文楷体'

# 字体大小(20是基准单位,18表示18px)

font.height = 20 * 18

# 是否使用粗体

font.bold = True

# 是否使用斜体

font.italic = False

# 字体颜色

font.colour_index = 1

header_style.font = font


# 表头垂直居中对齐

align = xlwt.Alignment()

# 垂直方向的对齐方式

align.vert = xlwt.Alignment.VERT_CENTER

# 水平方向的对齐方式

align.horz = xlwt.Alignment.HORZ_CENTER

header_style.alignment = align


# 给表头加上红色的虚线边框

borders = xlwt.Borders()

props = (

    ('top', 'top_colour'), ('right', 'right_colour'),

    ('bottom', 'bottom_colour'), ('left', 'left_colour')

)

# 通过循环对四个方向的边框样式及颜色进行设定

for position, color in props:

    setattr(borders, position, xlwt.Borders.DASHED)

    setattr(borders, color, 2)

header_style.borders = borders


# 调整单元格的宽度(列宽)和表头的高度(行高)

# 设置行高为40px

sheet.row(0).set_style(xlwt.easyxf(f'font:height {20 * 40}'))

titles = ('姓名', '语文', '数学', '英语')

for index, title in enumerate(titles):

    # 设置列宽为1500px

    sheet.col(index).width = 20 * 150



# 添加表头数据

titles = ('姓名', '语文成绩', '数学成绩', '英语成绩')

for index, title in enumerate(titles):

    sheet.write(0, index, title, header_style)


# 将学生姓名和考试成绩写入单元格

for row in range(len(scores)):

    sheet.write(row + 1, 0, names[row])

    for col in range(len(scores[row])):

        sheet.write(row + 1, col + 1, scores[row][col])

# 保存Excel工作簿

wb.save('考试成绩表.xlsx')


简单计算

计算刚才的考试成绩表.xlsx里面每个人的平均成绩


# 计算考试成绩.xls文件中每个人的平均成绩

import xlrd

import xlwt

from xlutils.copy import copy


wb1 = xlrd.open_workbook('考试成绩表.xls')


# 不改变原数据,将元数据拷贝在另外一个表中

wb2 = copy(wb1)  # type: xlwt.Workbook

sheet = wb2.get_sheet(0)

sheet.write(0, 4, '平均分')

for row_index in range(1, 4):

    sheet.write(row_index, 4, xlwt.Formula(f'average(B{row_index + 1}:D{row_index + 1})'))

wb2.save('考试成绩表—平均成绩.xls')


openpyxl读取Excel文件

import openpyxl

from datetime import datetime


# 加载一个工作簿 

wb = openpyxl.load_workbook('股票数据.xlsx')

print(type(wb))


# 获取工作表的名字

print(wb.sheetnames)


# 获取工作表 

# sheet = wb['股票数据']  

sheet = wb.worksheets[0]


# 工作表类型

print(type(sheet)) #


# 工作表维度

print(sheet.dimensions) # A1:G255


# 工作表的长度和宽度

print(sheet.max_row, sheet.max_column) # 255 7

操作Word文档

这里我们会用到两个模块python-docx、pillow,一个用于处理word文档,一个用于处理图像。


创建一个word文档

from docx import Document

from docx.shared import Inches

from docx.document import Document as Doc


# 创建一个Document对象

document = Document()  # type:Doc


# 添加一个标题 0 ,最高级标题

document.add_heading('三国', 0)


# 添加段落

p = document.add_paragraph('三国(220年-280年)是中国历史上位于汉朝之后、晋朝之前的一段历史时期。\

                           这一个时期,先后出现了曹魏、蜀汉、东吴三个主要政权。263年,蜀汉后主刘禅投降,\

                           蜀汉被魏所灭。265年司马昭去世,其子司马炎夺取曹魏政权,定都洛阳,建立晋朝,\

                           史称西晋。280年司马炎大举进攻吴国,孙吴灭亡,西晋统一天下,至此,')


p.add_run('近百年的战乱结束,').bold = True  # 加粗

p.add_run('三家归晋。').italic = True  # 斜体


# 一级标题

document.add_heading('三国历史简介', level = 1)

document.add_paragraph('人物简介', style = 'Intense Quote')


document.add_paragraph(

    '曹魏阵营', style = 'List Bullet'

)

document.add_paragraph(

    '曹操:', style = 'List Number'

)

document.add_paragraph(

    '郭嘉:', style = 'List Number'

)


# 添加图片

document.add_picture('三国.jpg', width = Inches(4))


records = (

    ('刘备', '男', '蜀汉'),

    ('孙权', '男', '东吴'),

    ('曹丕', '男', '曹魏'),

    ('吕布', '男', '群雄')

)


# 添加一个表格

table = document.add_table(rows = 1, cols = 3)

hdr_cells = table.rows[0].cells

hdr_cells[0].text = '姓名'

hdr_cells[1].text = '性别'

hdr_cells[2].text = '势力'

for qty, id, desc in records:

    row_cells = table.add_row().cells

    row_cells[0].text = str(qty)

    row_cells[1].text = id

    row_cells[2].text = desc


document.add_page_break()


# 保存文档,命名为 三国.docx

document.save('三国.docx')


生成样板文章

from docx import Document

from docx.document import Document as Doc


# 读取 离职证明.docx 文档

doc = Document('离职证明.docx')  # type:Doc


# 循环输出文档内容

for i, paragraph in enumerate(doc.paragraphs):

    print(i, paragraph.text)


# 将文档中’曹操‘用’曹丕‘替代

for paragraph in doc.paragraphs:

    if '曹操' in paragraph.text:

        for run in paragraph.runs:

            run.text = run.text.replace('曹操', '曹丕')


# 另存为 离职证明(新).docx

doc.save('离职证明(新).docx')

Word就简单介绍一下了。


操作PDF文件

在Python中,可以使用PyPDF2的三方库来读取PDF文件,安装的方法就不多说了。


虽然PyPDF2不能从PDF文档中提取图像、图表或其他媒体,但它可以提取文本,并将其返回为Python字符串。


读取PDF文件

import PyPDF2

from PyPDF2.pdf import PageObject


# 读取PDF文件

reader = PyPDF2.PdfFileReader('XGBOOST.pdf')

# 写模式

writer = PyPDF2.PdfFileWriter()


for page_num in range(reader.numPages):

    current_page = reader.getPage(page_num)  # type: PageObject

    # 从页面中抽取文字

    # print(current_page.extractText())

    # 旋转页面

    current_page.rotateClockwise(90)

    writer.addPage(current_page)

    # 添加一个空白页

    writer.addBlankPage()


# 保存至 XGBOOS-newT.pdf

with open('XGBOOS-newT.pdf', 'wb') as file:

    writer.write(file)

加密PDF文件

import PyPDF2


# 读操作

reader = PyPDF2.PdfFileReader('XGBoost.pdf')

# 写操作

writer = PyPDF2.PdfFileWriter()

for page_num in range(reader.numPages):

    writer.addPage(reader.getPage(page_num))

    

# 加密PDF文件,密码为foobared

writer.encrypt('foobared')


# 将加密过的文件保存为 XGBoost_encrypted.pdf

with open('XGBoost_encrypted.pdf', 'wb') as file:

    writer.write(file)

我们还可以将上面的代码封装在一个函数里面


def encrypt_all(path, name, ept):

    """

    给PDF文件加密

    :param path:  文件路劲

    :param name:  文件名

    :param ept:   加密密码

    :return:  返回加密后的新文件

    """

    reader = PyPDF2.PdfFileReader(f'{path}/{name}.pdf')

    writer = PyPDF2.PdfFileWriter()

    for page_num in range(reader.numPages):

        writer.addPage(reader.getPage(page_num))

    # 加密PDF文件

    writer.encrypt(ept)

    with open(f'{path}/{name}_encrypted.pdf', 'wb') as file:

        writer.write(file)


创建PDF文件

这里我们需要用到一个三方库:reportlab


from reportlab.lib.pagesizes import A4

from reportlab.pdfbase import pdfmetrics

from reportlab.pdfbase.ttfonts import TTFont

from reportlab.pdfgen import canvas


# 注册字体文件

pdfmetrics.registerFont(TTFont('Font1', 'fonts/Vera.ttf'))

pdfmetrics.registerFont(TTFont('Font2', 'fonts/IPix中文像素字体.ttf'))


# 设置页面大小,当前为A4

pdf_canvas = canvas.Canvas('demo.pdf', pagesize = A4)

width, height = A4


# 绘图

image = canvas.ImageReader('guido.jpg')

pdf_canvas.drawImage(image, 20, height - 375, 250, 375)


# 显示当前页

pdf_canvas.showPage()


# 写入文字内容1 设置文字格式

pdf_canvas.setFont('Font2', 40)   

pdf_canvas.setFillColorRGB(1, 0, 0, 1)

pdf_canvas.drawString(width // 4 , height // 4, '我吕布天下无敌啊!')

# 写入文字内容2 设置文字格式

pdf_canvas.setFont('Font1', 40)

pdf_canvas.setFillColorRGB(0, 1, 0, 0.5)

pdf_canvas.rotate(18)

pdf_canvas.drawString(200, 280, 'nothing can defeat you')


# 保存

pdf_canvas.save()


添加水印

import PyPDF2


from PyPDF2.pdf import PageObject


# 待添加水印文件

reader1 = PyPDF2.PdfFileReader('XGBoost.pdf')

# 水印文件

reader2 = PyPDF2.PdfFileReader('watermark.pdf')

# 将前面两个文件合一,存入新的文件中

writer = PyPDF2.PdfFileWriter()


# 给每页添加水印

watermark_page = reader2.getPage(0)

for page_num in range(reader1.numPages):

    current_page = reader1.getPage(page_num)  # type: PageObject

    current_page.mergePage(watermark_page)

    writer.addPage(current_page)


# 保存

with open('resources/XGBoost-watermarked.pdf', 'wb') as file:

    writer.write(file)

知识补充:获取文件夹下所有内容


import os


# 获取指定文件夹下的所有内容

path = 'D:\\pycharm_DATA\\code\\day19'

files_list = os.listdir(path)

# print(files_list)


# 循环输出该路径下的文件

for file in files_list:

    fullpath = os.path.abspath(file)

    print(fullpath)


正则表达式

查找符合某些复杂规则的字符串时,比如在编写处理字符串的程序或网页时,就需要正则表达式来给我筛选我们想要的内容。简单来说,就是正则表达式指一种匹配字符串的模式,功能非常强大,但是它的匹配模式也很复杂。这里我推荐大家去阅读这篇文字,里面所说非常详细[正则表达式30分钟入门教程](正则表达式30分钟入门教程 (deerchao.cn))


基本符号

符号解释示例说明

.匹配任意字符b.t可以匹配bat / but / b#t / b1t等

\w匹配字母/数字/下划线b\wt可以匹配bat / b1t / b_t等

但不能匹配b#t

\s匹配空白字符(包括\r、\n、\t等)love\syou可以匹配love you

\d匹配数字\d\d可以匹配01 / 23 / 99等

\b匹配单词的边界\bThe\b

^匹配字符串的开始^The可以匹配The开头的字符串

$匹配字符串的结束.exe$可以匹配.exe结尾的字符串

\W匹配非字母/数字/下划线b\Wt可以匹配b#t / b@t等

但不能匹配but / b1t / b_t等

\S匹配非空白字符love\Syou可以匹配love#you等

但不能匹配love you

\D匹配非数字\d\D可以匹配9a / 3# / 0F等

\B匹配非单词边界\Bio\B

[]匹配来自字符集的任意单一字符[aeiou]可以匹配任一元音字母字符

[^]匹配不在字符集中的任意单一字符[^aeiou]可以匹配任一非元音字母字符

*匹配0次或多次\w*

+匹配1次或多次\w+

?匹配0次或1次\w?

{N}匹配N次\w{3}

{M,}匹配至少M次\w{3,}

{M,N}匹配至少M次至多N次\w{3,6}

| 分支foo|bar可以匹配foo或者bar

(?#)注释

(exp)匹配exp并捕获到自动命名的组中

(?exp)匹配exp并捕获到名为name的组中

(?:exp)匹配exp但是不捕获匹配的文本

(?=exp)匹配exp前面的位置\b\w+(?=ing)可以匹配I’m dancing中的danc

(?<=exp)匹配exp后面的位置(?<=\bdanc)\w+\b可以匹配I love dancing and reading中的第一个ing

(?!exp)匹配后面不是exp的位置

(?匹配前面不是exp的位置

*?重复任意次,但尽可能少重复a.*b

a.*?b将正则表达式应用于aabab,前者会匹配整个字符串aabab,后者会匹配aab和ab两个字符串

+? 重复1次或多次,但尽可能少重复

??重复0次或1次,但尽可能少重复

{M,N}?重复M到N次,但尽可能少重复

{M,}?重复M次以上,但尽可能少重复

re 模块

python还提供 re 模块来支持正则表达式个各种操作,下面是 re 模块中的一些重要函数


函数说明

compile(pattern, flags=0)编译正则表达式返回正则表达式对象

match(pattern, string, flags=0)用正则表达式匹配字符串 成功返回匹配对象 否则返回None

search(pattern, string, flags=0)搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None

split(pattern, string, maxsplit=0, flags=0)用正则表达式指定的模式分隔符拆分字符串 返回列表

sub(pattern, repl, string, count=0, flags=0)用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数

fullmatch(pattern, string, flags=0)match函数的完全匹配(从字符串开头到结尾)版本

findall(pattern, string, flags=0)查找字符串所有与正则表达式匹配的模式 返回字符串的列表

finditer(pattern, string, flags=0) 查找字符串所有与正则表达式匹配的模式 返回一个迭代器

purge()清除隐式编译的正则表达式的缓存

re.I / re.IGNORECASE忽略大小写匹配标记

re.M / re.MULTILINE多行匹配标记

实例

实例1:判断用户名、QQ号码、手机号码是否有效


import re


# 判断用户的用户名是否复合用户名命名规则

username = input('请输入用户名: ')


#username_pattern = re.compile(r'^\w{6,20}$') # 通过compile编译正则表达式创建Pattern对象

#matcher = username_pattern.match(username)

matcher = re.match(r'^\w{6,20}$', username)

if matcher is None:

    print('无效用户名')

else:

    print(matcher)

    print(matcher.group())

    

"""

# 判断QQ号是否有效

qq = input('请输入QQ号: ')

matcher = re.match(r'[1-9]\d{4,}', qq)

if matcher is None:

    print('无效QQ')

else:

    print(matcher)

    print(matcher.group())

"""

    

"""

# 判断手机号码是否有效

telephone = input('请输入手机号码: ')

matcher = re.match(r'1[3-9]\d{9}$', telephone)

if matcher is None:

    print('无效手机号码')

else:

    print(matcher)

    print(matcher.group())

"""    


实例2:从字符串中提取跟正则表达式匹配的部分


import re


# match - 匹配 - 从头开始进行匹配 

# search - 搜索 - 从任意位置匹配 

# findall - 从字符串中找出所有和正则表达式匹配的内容


# 从字符串中提取跟正则表达式匹配的部分

content = """报警电话:110,我们班是Python-2105班,

我的QQ号是123456789,我的手机号是98765432104,谢谢!"""


# 创建正则表达式对象

pattern = re.compile(r'\d+')

# 从任意位置匹配 

matcher = pattern.search(content)

while matcher:

    print(matcher.group())

    # 匹配到的开始位置,结束位置

    print(matcher.start(), matcher.end())

    matcher = pattern.search(content, matcher.end())


# 从字符串中找出所有和正则表达式匹配的内容

results = pattern.findall(content)

for result in results:

    print(result)


results = re.findall(r'\d+', content)

for result in results:

    print(result)


实例3:正则表达式捕获组


import re


import requests


# 匹配整个a标签,但是只捕获()中的内容 ---> 正则表达式的捕获组

pattern = re.compile(r'')

resp = requests.get('https://www.sohu.com/')

results = pattern.findall(resp.text)

for href, title in results:

    print(title)

    print(href)

实例4:过滤不良内容


import re


content = '马化腾是一个沙雕煞笔,FUck you!'

pattern = re.compile(r'[傻沙煞][逼笔雕鄙]|笨蛋|fuck|shit', flags=re.IGNORECASE)

# modified_content = re.sub(r'[傻沙煞][逼笔雕鄙]|笨蛋|fuck|shit', '*', content, flags=re.I)

modified_content = pattern.sub('*', content)

print(modified_content)

实例5:正则表达式拆分字符串


import re


poem = '窗前明月光,疑是地上霜。举头望明月,低头思故乡。'

# sentences_list = re.split(r',|。', poem)

# sentences_list = re.split(r'[,。]', poem)

pattern = re.compile(r'[,。]')

sentences_list = pattern.split(poem)

print(sentences_list)

sentences_list = [sentence for sentence in sentences_list if sentence]

print(sentences_list)

for sentence in sentences_list:

    print(sentence)



关注公众号,每天可以领红包


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/190108