python

Python

迭代器的使用

迭代器是一个可以逐个访问集合元素的对象,可以使用for循环来遍历集合中的每个元素。在Python中,迭代器是一个实现了__iter__()__next__()方法的对象,其中__iter__()方法返回迭代器对象自身,__next__()方法返回集合中的下一个元素。

迭代器的工作原理是通过不断调用__next__()方法来获取集合中的下一个元素,直到集合中没有元素可供访问时抛出StopIteration异常。因此,迭代器是一种惰性计算的方式,只有在需要时才会计算下一个元素。

使用迭代器可以极大地简化代码,提高代码的可读性和可维护性。可以通过iter()函数将可迭代对象转换为迭代器,然后使用next()函数来获取下一个元素。另外,也可以使用for循环来遍历迭代器中的元素。

下面是一个简单的示例,展示了如何使用迭代器来遍历一个列表:

# 创建一个列表
my_list = [1, 2, 3, 4, 5]
​
# 将列表转换为迭代器
my_iter = iter(my_list)
​
# 使用next()函数获取下一个元素
print(next(my_iter))  # 输出:1
print(next(my_iter))  # 输出:2
​
# 使用for循环遍历迭代器中的元素
for element in my_iter:
    print(element)

迭代器是Python中一个非常重要的概念,可以帮助我们高效地处理集合中的元素。通过理解迭代器的原理和使用方法,可以更好地利用Python的强大功能来简化代码逻辑。

模块与包的使用

在Python中,模块是一种组织代码的方式,可以将相关的代码封装在一个文件中,并通过import语句在其他文件中引入并使用。模块的原理和使用如下所述:

模块的原理:

  1. 模块文件:模块通常是一个以.py为扩展名的Python文件,其中包含了一些函数、变量、类等代码。

  2. 命名空间:每个模块都有自己的命名空间,模块中定义的函数、变量等都位于该命名空间中,可以避免命名冲突。

  3. import语句:使用import语句可以在一个Python文件中引入其他模块,从而可以使用该模块中定义的函数、变量等。

  4. 模块搜索路径:Python解释器会按照一定的搜索路径来查找要引入的模块,包括当前目录、标准库目录、第三方库目录等。

模块的使用:

模块

  1. 引入模块:使用import语句引入模块,语法如下:

    import module_name

    或者

    from module_name import function_name, variable_name
  2. 使用模块中的内容:引入模块后,可以通过.操作符访问模块中定义的函数、变量等,例如:

    import math
    print(math.sqrt(16))
  3. 重命名模块:可以使用as关键字给模块起一个别名,方便使用,例如:

    import math as m
    print(m.sqrt(16))
  4. 查看模块内容:可以使用dir()函数查看模块中定义的所有函数、变量等,例如:

    import math
    print(dir(math))
  5. 自定义模块:可以创建自己的模块文件,将相关代码封装在其中,然后在其他文件中引入并使用。

  6. 模块的搜索路径:可以通过sys.path来查看Python解释器的模块搜索路径,也可以将自定义模块所在的路径添加到搜索路径中。

在Python中,包(Package)是一种组织模块的方式,可以将多个相关的模块组织在一个目录下,形成一个包。包的原理和使用如下所述:

包的原理:

  1. 目录结构:包是一个包含__init__.py文件的目录,__init__.py文件可以为空,也可以包含包的初始化代码。

  2. 命名空间:包中的模块都位于包的命名空间中,可以避免不同包中的模块之间的命名冲突。

  3. import语句:可以使用import语句引入包中的模块,语法为import package_name.module_name

  4. 子包:包内部可以再包含子包,形成多层次的包结构,子包也是一个包,可以包含模块和子包。

包的使用:

  1. 创建包:创建一个包的步骤如下:

    • 在一个目录下创建一个以包名命名的目录,例如my_package

    • 在该目录下创建一个__init__.py文件,可以为空。

    • 在包目录下创建模块文件,例如module1.pymodule2.py等。

  2. 引入包:使用import语句引入包中的模块,语法如下:

    import my_package.module1
  3. 使用包中的模块:引入包中的模块后,可以通过.操作符访问模块中定义的函数、变量等,例如:

    import my_package.module1
    my_package.module1.function_name()
  4. __init__.py文件__init__.py文件可以包含一些初始化包的代码,例如导入包内的模块、定义包级别的变量等。

  5. 相对导入:可以使用相对导入来引入包内的模块,例如:

    from . import module1
    
  6. 查看包内容:可以使用dir()函数查看包中定义的所有模块、子包等,例如:

    import my_package
    print(dir(my_package))
    
常用模块

在Python中有很多常用的模块,每个模块都提供了一些功能强大的工具和函数,可以帮助我们更高效地编写代码。以下是一些常用的Python模块的详细解释:

  1. os:提供了访问操作系统功能的接口,可以用于文件操作、路径操作、环境变量等。常用函数包括os.path.join()os.listdir()os.getcwd()等。

  2. sys:提供了与Python解释器进行交互的函数和变量,可以用于命令行参数、标准输入输出、异常处理等。常用函数包括sys.argvsys.stdinsys.stdout等。

  3. datetime:提供了日期和时间处理的功能,可以用于日期时间的创建、格式化、计算等。常用类包括datetime.datetimedatetime.datedatetime.timedelta等。

  4. random:提供了生成随机数的功能,可以用于模拟数据、密码生成、游戏等。常用函数包括random.random()random.randint()random.choice()等。

  5. math:提供了数学运算的函数,可以用于数学计算、三角函数、对数函数等。常用函数包括math.sqrt()math.sin()math.log()等。

  6. re:提供了正则表达式操作的功能,可以用于字符串匹配、替换、分割等。常用函数包括re.match()re.search()re.sub()等。

  7. json:提供了JSON数据的编码和解码功能,可以用于处理JSON格式的数据。常用函数包括json.dumps()json.loads()等。

  8. requests:提供了HTTP请求的功能,可以用于发送HTTP请求、处理响应等。常用函数包括requests.get()requests.post()requests.put()等。

  9. csv:提供了CSV文件的读写功能,可以用于处理逗号分隔的数据文件。常用函数包括csv.reader()csv.writer()csv.DictReader()等。

  10. pandas:提供了数据分析和处理的功能,可以用于数据结构、数据清洗、数据分析等。常用类包括pandas.DataFramepandas.Seriespandas.read_csv()等。

日志模块logging

1 什么是日志?

日志是对软件执行时所发生事件的一种追踪方式。软件开发人员对他们的代码添加日志调用,借此来指示某事件的发生。一个事件通过一些包含变量数据的描述信息来描述(比如:每个事件发生时的数据都是不同的)。开发者还会区分事件的重要性,重要性也被称为 等级 或 严重性,也即日志级别。

在工作当中,我们写的程序必须要有记录日志的功能,以便在出现问题时能够更快的定位到问题。而日志是有级别的,级别相关说明如下表:

log level描述
debug程序或系统的调试信息
info一般信息
notice不影响正常功能,需要注意的消息
warning/warn可能影响系统功能,需要提醒用户的重要事件
err/error错误信息
crit紧急,比较严重的
alert必须马上处理的
emerg/panic会导致系统不可用的
**表示所有的日志级别
none与*相反,表示啥也没有

以上日志级别从低到高排序,级别越低,信息越详细。

2 什么时候使用日志

对于简单的日志使用来说日志功能提供了一系列便利的函数。它们是 debug(),info(),warning(),error() 和 critical()。想要决定何时使用日志,请看下表,其中显示了对于每个通用任务集合来说最好的工具。

你想要执行的任务此任务的最好工具
对于命令行或程序的应用,结果显示在控制台print()
当有诊断目的需要详细输出信息时logging.debug()函数
在对程序的普通操作发生时提交事件报告 (比如:状态监控和错误调查)logging.info()函数
提出一个警告信息基于一个特殊的运行时事件warnings.warn()位于代码库中,该事件是可以避免的,需要修改客户端应用以消除告警 logging.warning()不需要修改客户端应用,但是该事件还是需要引起关注
对一个特殊的运行时事件报告错误引发异常
报告错误而不引发异常(如在长时间运行中的服务端进程的错误处理)logging.error(), logging.exception()或 logging.critical()分别适用于特定的错误及应用领域

3 logging模块

3.1 logging日志级别

日志功能应以所追踪事件级别或严重性而定。各级别适用性如下(以严重性递增):

级别何时使用
DEBUG细节信息,仅当诊断问题时适用
INFO确认程序按预期运行
WARNING表明有已经或即将发生的意外(例如:磁盘空间不足)。程序仍按预期进行
ERROR由于严重的问题,程序的某些功能已经不能正常执行
CRITICAL严重的错误,表明程序已不能继续执行

可见在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有

参数描述
filename用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中
filemode文件打开方式,在指定了filename时使用这个参数,默认值为a
format指定handler使用的日志显示格式
datefmt指定日期时间格式
level设置rootlogger的日志级别
stream用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或文件(f=open(’test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。

format参数中可能用到的格式化类型

格式化类型描述
%(name)sLogger的名字
%(levelno)s数字形式的日志级别
%(levelname)s文本形式的日志级别
%(pathname)s调用日志输出函数的模块的完整路径名,可能没有
%(filename)s调用日志输出函数的模块的文件名
%(module)s调用日志输出函数的模块名
%(funcName)s调用日志输出函数的函数名
%(lineno)d调用日志输出函数的语句所在的代码行
%(created)f当前时间,用UNIX标准的表示时间的浮点数表示
%(relativeCreated)d输出日志信息时的,自Logger创建以来的毫秒数
%(asctime)s字符串形式的当前时间。默认格式是’2019-08-15 17:00:00,896’ 逗号后面的是毫秒。
%(thread)d线程ID。可能没有
%(threadName)s线程名。可能没有
%(process)d进程ID。可能没有
%(message)s用户输出的消息
  1. Logger(记录器):Logger是logging模块的核心概念,用于向不同的输出目标记录日志消息。每个Logger对象都有一个名称,可以通过logging.getLogger(name)方法获取Logger实例。Logger对象可以设置日志级别(如DEBUG、INFO、WARNING、ERROR、CRITICAL),用于控制日志消息的重要性。

  2. Handler(处理器):Handler负责将日志消息发送到不同的目的地,比如文件、终端、邮件等。logging模块提供了多种内置的Handler,如StreamHandler(输出到控制台)、FileHandler(输出到文件)、SMTPHandler(发送邮件)等。可以根据需求选择合适的Handler,也可以自定义Handler来满足特定需求。

  3. Formatter(格式化器):Formatter定义了日志消息的输出格式,包括时间戳、日志级别、消息内容等。通过Formatter对象,可以自定义日志消息的显示方式,例如添加额外的信息、调整显示格式等。常见的格式化字符串包括%(asctime)s(时间)、%(levelname)s(日志级别)、%(message)s(消息内容)等。

  4. Filter(过滤器):Filter用于过滤日志消息,可以根据特定条件决定是否记录某条日志消息。通过Filter对象,可以实现更细粒度的日志控制,例如只记录特定级别的日志、根据消息内容过滤等。自定义Filter可以根据实际需求编写,以实现更复杂的日志过滤逻辑。

使用logging模块记录日志的一般步骤如下:

  1. 导入logging模块:import logging

  2. 创建Logger对象:logger = logging.getLogger('my_logger')

  3. 创建Handler对象:handler = logging.FileHandler('app.log')

  4. 创建Formatter对象:formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

  5. 将Formatter对象添加到Handler对象:handler.setFormatter(formatter)

  6. 将Handler对象添加到Logger对象:logger.addHandler(handler)

  7. 设置日志级别:logger.setLevel(logging.DEBUG)

  8. 记录日志消息:logger.debug('This is a debug message')

import logging

# 创建Logger对象
logger = logging.getLogger('my_logger')

# 创建Handler对象
handler = logging.FileHandler('app.log')

# 创建Formatter对象
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 将Formatter对象添加到Handler对象
handler.setFormatter(formatter)

# 将Handler对象添加到Logger对象
logger.addHandler(handler)

# 设置日志级别
logger.setLevel(logging.DEBUG)

# 记录日志消息
logger.debug('This is a debug message')
异常处理

在Python中,异常处理是一种机制,用于处理程序执行过程中可能出现的错误或异常情况。当程序运行时遇到错误或异常时,会抛出一个异常对象,如果没有适当的处理机制,程序将会中断并显示错误信息。

Python中的异常处理通过try-except语句来实现。try语句用于包裹可能会出现异常的代码块,except语句用于捕获并处理这些异常。如果try块中的代码执行过程中发生了异常,Python会跳转到对应的except块,执行其中的代码,然后程序会继续执行。

以下是一个简单的异常处理示例:

try:
    x = 10 / 0
except ZeroDivisionError:
    print("除数不能为0")

在这个示例中,try块中的代码会尝试计算10除以0,这会引发一个ZeroDivisionError异常。然后程序会跳转到except块,执行其中的代码,输出"除数不能为0"。

除了捕获特定类型的异常外,还可以使用except语句来捕获所有类型的异常,如下所示:

try:
    x = 10 / 0
except:
    print("发生了异常")

此外,可以使用多个except块来处理不同类型的异常:

try:
    x = 10 / 0
except ZeroDivisionError:
    print("除数不能为0")
except ArithmeticError:
    print("发生了算术错误")

除了try-except语句外,还可以使用finally块来执行无论是否发生异常都需要执行的代码,例如关闭文件或释放资源:

try:
    f = open("file.txt", "r")
    # 执行一些操作
except IOError:
    print("文件打开错误")
finally:
    f.close()

对于python而言,异常是作为类存在的,而类实例化以后就是一个对象。这个对象本身并不是对所有异常都一样,它是在解释器捕获到异常以后根据异常本身所属的类别,去临时生成的一 个异常对象,然后将这个异常所发生的信息给输出到标准输出中并中止程序运行。

异常对象:

  • python异常是内置的经典类Exception的子类的实例:

    • 为了向后兼容,python还允许使用字符串或任何经典类实例

    • python2.5之后,Exception是从BaseException继承的新式类

  • python自身引发的所有异常都是Exception的子类的实例。

  • 大多的标准异常都是由StandardError派生的,其有3个抽象的子类:

    • ArithmeticError:

      • 由于算术错误而引发的异常基类

      • OverflowError,ZeroDivisionError,FloatingPointError

    • LookupError:

      • 容器在接收到一个无效键或索引时引发的异常的基类

      • IndexError,KeyError

    • EnvironmentError:

      • 由于外部原因而导致的异常的基类

      • IOError,OSError,WindowsError

python中的标准异常类:

  • AssertionError:断言语句失败

  • AttributeError:属性引用或赋值失效

  • FloatingPointError:浮点型运算失败

  • IOError:I/O操作失败

  • ImportError:import语句不能找到要导入的模块,或者不能找到该模块特别请求的名称

  • IndentationError:解析器遇到了一个由于错误的缩进而引发的语法错误

  • IndexError:用来索引序列的整数超出了范围

  • KeyError:用来索引映射的键不在映射中

  • KeyboardInterrupt:用户按了中断键(Ctrl+c,Ctrl+Break或Delete键)

  • MemoryError:运算耗尽内存

  • NameError:引用了一个不存在的变量名

  • NotImplementedError:由抽象基类引发的异常,用于指示一个具体的子类必须覆盖一个方法

  • OSError:由模块os中的函数引发的异常,用来指示平台相关的错误

  • OverflowError:整数运算的结果太大导致溢出

  • SyntaxError:语法错误

  • SystemError:python本身或某些扩展模块中的内部错误

  • TypeError:对某对象执行了不支持的操作

  • UnboundLocalError:引用未绑定值的本地变量

  • UnicodeError:在Unicode的字符串之间进行转换时发生的错误

  • ValueError:应用于某个对象的操作或函数,这个对象具有正确的类型,但却有不适当的值

  • WindowsError:模块os中的函数引发的异常,用来指示与windows相关的错误

  • ZeroDivisionError:除数为0

python中自定义异常类: 自定义异常和多重继承: 较有效的方法是从自定义异常类和标准异常进行多重继承,例如:

class CustomAttributeError(CustomException, AttributeError):
    pass

标准库中使用的其它异常: python标准库中的许多模块都定义了自己的异常类,如socket中的socket.error就等同于自定义的异常类 assert语句:assert语句用于在程序中引入调试代码。语法如下:

assert condition[, expression]

如果condition条件满足,则assert不做任何操作;如果condition条件不满足,则assert使用expression作为参数实例化AssertionError并引发结果实例 注意:

  • 如果运行python时使用了”-O“优化选项,则assert将是一个空操作:编译器不为assert语句生成代码

  • 如果运行python时不使用”-O“选项,则debug内置变量为True,否则其值为False

assert语句相当于以下代码:

if __debug__:
    if not condition:
    raise AssertionError, <expression>
正则表达式re模块

在Python中,re模块是用于处理正则表达式的模块,它提供了一组函数来进行正则表达式的匹配、搜索和替换操作。

下面是一些re模块中常用的函数:

  1. re.compile(pattern, flags=0):编译正则表达式,返回一个正则表达式对象。可以通过该对象进行匹配、搜索和替换操作。

  2. re.match(pattern, string, flags=0):尝试从字符串的起始位置匹配一个模式,如果匹配成功则返回一个匹配对象,否则返回None。

  3. re.search(pattern, string, flags=0):在字符串中搜索模式,如果找到匹配则返回一个匹配对象,否则返回None。

  4. re.findall(pattern, string, flags=0):在字符串中查找所有匹配的子串,并返回一个包含所有匹配结果的列表。

  5. re.sub(pattern, repl, string, count=0, flags=0):在字符串中查找匹配的子串,并用指定的字符串替换它。可以通过count参数指定最多替换的次数。

除了上述函数之外,re模块还提供了一些常用的正则表达式标志,如re.IGNORECASE(忽略大小写)、re.MULTILINE(多行匹配)等,可以在编译正则表达式时使用这些标志来修改匹配的行为。

1 正则表达式概念

正则表达式(RE)是一种小型的、高度专业化的编程语言,在python中,它通过re模块实现。

正则表达式可以实现以下功能:

  • 为想要匹配的相应字符串集指定规则;

  • 能够匹配不定长的字符集;

  • 可以指定正则表达式的一部分的重复次数;

  • 可以使用RE以各种方式来修改或分割字符串

正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行。

2 字符匹配
2.1 普通字符:
  • 多数字母和字符一般都会和自身匹配。

  • 如正则表达式test会和字符串"test"完全匹配

import re
r = re.findall('el','hello world')
print(r)
2.2 元字符:. ^ $ * + ? {} [] | () \

2.2.1 元字符之 .

. 默认用来匹配除换行符(\n)之外的任意单个字符 编译时指定flag DOTALL则匹配任意单个字符,包括换行

import re

ret = re.findall('r..time', 'helloruntime')
print(ret)  # ['runtime']

2.2.2 元字符之 ^

^ 用于匹配行首。除非设置MULTILINE标志,它只是匹配字符串的开始 在MULTILINE模式里,它也可以直接匹配字符串中的每个换行

解释import re

ret = re.findall('^r..time', 'hellorootime')
print(ret)  # []

ret = re.findall('^h..lo', 'hellorootime')
print(ret)  # ['hello']

2.2.3 元字符之 $

$ 用于匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置

import re

ret = re.findall('time$', 'hellorootime')
print(ret)  # ['time']

2.2.4 元字符之 *

* 用于指定前一个字符可以被匹配零次或更多次,而不是只有一次。 匹配引擎会试着重复尽可能多的次数(不超过整数界定范围,20亿)

解释import re

ret=re.findall('abc*','abcccc')     # 贪婪匹配[0,+oo]
print(ret)  # ['abcccc']

ret=re.findall('abc*','ab')
print(ret)  # ['ab']

2.2.5 元字符之 +

+ 用于表示匹配至少一次或多次

解释import re

ret=re.findall('abc+','abcccc')     #[1,+oo]
print(ret)  # ['abcccc']

ret=re.findall('abc+','ab')
print(ret)  # []

2.2.6 元字符之 ?

? 用于匹配一次或零次:你可以认为它用于标识某事物是可选的 加在重复(+和*)的后面,可以启用懒惰模式,实现最小匹配

解释import re

ret=re.findall('abc?','abccc')      # [0,1]
print(ret)      # ['abc']

ret=re.findall('abc*?','abccc')      # [0]
print(ret)      # ['ab']

ret=re.findall('abc+?','abccc')      # [1]
print(ret)      # ['abc']

注意:前面的*和+以及?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配

2.2.7 元字符之 {m,n}

{m,n} 用于匹配指定次数,其中m和n是十进制整数。该限定符的意思是至少有m个重复、至多到n个重复

忽略m会认为下边界是0,而忽略n的结果将是上边界为无穷大(实际上是20亿)

{0,}等同于,{1}等同于+,而{0,1}则与?相同。若可以的话,最好使用、+或?

解释import re

ret=re.findall('abc{1,3}','abccc')
print(ret)      # ['abccc']

ret=re.findall('abc{1,3}','abc')
print(ret)      # ['abc']

ret=re.findall('abc{1,3}','ab')
print(ret)      # []

ret=re.findall('abc{0,}','abccccc')
print(ret)      # [abccccc]

ret=re.findall('abc{0,1}','abccccc')
print(ret)      # [abc]

ret=re.findall('abc{1}','abccccc')
print(ret)      # [abc]

ret=re.findall('abc{1,3}','abccccccccc')
print(ret)      # ['abccc']

2.2.8 元字符之 []

[] 常用来指定一个字符集:[abc]或[a-z] 元字符在字符集中不起作用:[akm$] 在[]内以^开头表示匹配不在区间范围内的字符:a-z

解释import re

ret = re.findall('a[bc]d', 'acd')
print(ret)  # ['acd']

ret = re.findall('[a-z]', 'acd')
print(ret)  # ['a', 'c', 'd']

ret = re.findall('[.*+]', 'a.cd+')
print(ret)  # ['.', '+']

# 在字符集里有功能的符号: - ^ \

ret = re.findall('[1-9]', '45dha3')
print(ret)  # ['4', '5', '3']

ret = re.findall('[^ab]', '45bdha3')
print(ret)  # ['4', '5', 'd', 'h', '3']

ret = re.findall('[\d]', '45bdha3')
print(ret)  # ['4', '5', '3']

2.2.9 元字符之 \

反斜杠后面可以加不同的字符以表示不同特殊意义

反斜杠后边跟元字符去除特殊功能,比如. 反斜杠后边跟普通字符实现特殊功能,比如\d

字符描述
\d匹配任何十进制数;它相当于类 [0-9]
\D匹配任何非数字字符;它相当于类 0-9
\s匹配任何空白字符;它相当于类 [ \t\n\r\f\v]
\S匹配任何非空白字符;它相当于类 \t\n\r\f\v
\w匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]
\W匹配任何非字母数字字符;它相当于类 a-zA-Z0-9_
\b匹配一个特殊字符边界,比如空格 ,&,#等
解释ret = re.findall('I\b','I am LIST')
print(ret)      # []
ret = re.findall(r'I\b','I am LIST')
print(ret)      # ['I']

python正则表达式

正则表达式是一种用来匹配字符串的模式,可以用来查找、替换和提取字符串中的特定内容。在Python中,可以使用re模块来使用正则表达式。

以下是一些常用的正则表达式语法:

  1. 字符匹配:

  • \d:匹配任意数字

  • \D:匹配任意非数字字符

  • \w:匹配任意字母、数字和下划线

  • \W:匹配任意非字母、数字和下划线字符

  • \s:匹配任意空白字符

  • \S:匹配任意非空白字符

  • .:匹配任意字符(除了换行符)

  1. 重复匹配:

  • *:匹配前面的字符0次或多次

  • +:匹配前面的字符1次或多次

  • ?:匹配前面的字符0次或1次

  • {n}:匹配前面的字符恰好n次

  • {n,}:匹配前面的字符至少n次

  • {n,m}:匹配前面的字符至少n次,最多m次

  1. 边界匹配:

  • ^:匹配字符串的开头

  • $:匹配字符串的结尾

  • \b:匹配单词边界

  1. 分组匹配:

  • (...):将括号内的内容作为一个分组

  • |:匹配两个或多个表达式之一

  1. 贪婪匹配:

  • *?:匹配前面的字符0次或多次,但尽可能少匹配

  • +?:匹配前面的字符1次或多次,但尽可能少匹配

在使用正则表达式时,可以使用re模块中的函数来进行匹配、搜索和替换操作,例如re.match()、re.search()和re.sub()等。

以下是一个简单的示例,演示如何使用正则表达式来匹配一个邮箱地址:

import re
​
# 定义一个邮箱地址的正则表达式
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
​
# 要匹配的字符串
text = "我的邮箱地址是example@example.com,请给我发邮件。"
​
# 使用re.search()函数进行匹配
match = re.search(pattern, text)
​
if match:
    print("找到邮箱地址:", match.group())
else:
    print("未找到邮箱地址")

在Python中,可以使用re模块来进行正则表达式的运算,包括匹配、搜索、替换等操作。下面是一些常用的正则表达式运算:

  1. re.match(pattern, string, flags=0):从字符串的开头开始匹配模式,如果匹配成功则返回一个匹配对象,否则返回None。

import re
​
pattern = r'\d+'
string = '123abc'
​
match = re.match(pattern, string)
​
if match:
    print("匹配成功")
else:
    print("匹配失败")
  1. re.search(pattern, string, flags=0):在整个字符串中搜索匹配模式,如果找到则返回一个匹配对象,否则返回None。

import re
​
pattern = r'\d+'
string = 'abc123def'
​
match = re.search(pattern, string)
​
if match:
    print("找到匹配:", match.group())
else:
    print("未找到匹配")
  1. re.findall(pattern, string, flags=0):在字符串中查找所有匹配模式的子串,并返回一个包含所有匹配结果的列表。

import re
​
pattern = r'\d+'
string = 'abc123def456ghi'
​
matches = re.findall(pattern, string)
​
print("所有匹配结果:", matches)
  1. re.sub(pattern, repl, string, count=0, flags=0):用repl替换字符串中匹配模式的子串,count表示替换的次数。

import re
​
pattern = r'\d+'
repl = 'NUM'
string = 'abc123def456ghi'
​
new_string = re.sub(pattern, repl, string)
​
print("替换后的字符串:", new_string)
  1. re.split(pattern, string, maxsplit=0, flags=0):根据匹配模式对字符串进行分割,并返回一个列表。

import re
​
pattern = r'\d+'
string = 'abc123def456ghi'
​
parts = re.split(pattern, string)
​
print("分割后的结果:", parts)
  1. re.finditer(pattern, string, flags=0):在字符串中查找所有匹配模式的子串,并返回一个迭代器,每个元素是一个匹配对象。

import re
​
pattern = r'\d+'
string = 'abc123def456ghi'
​
matches_iter = re.finditer(pattern, string)
​
for match in matches_iter:
    print("找到匹配:", match.group())
  1. re.fullmatch(pattern, string, flags=0):尝试完全匹配整个字符串,如果成功则返回一个匹配对象,否则返回None。

import re
​
pattern = r'\d+'
string = '123'
​
match = re.fullmatch(pattern, string)
​
if match:
    print("完全匹配成功")
else:
    print("完全匹配失败")
  1. re.compile(pattern, flags=0):将正则表达式的模式编译成正则表达式对象,可以提高多次使用相同模式的效率。

import re

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

string = 'abc123def456ghi'
matches = regex.findall(string)

print("所有匹配结果:", matches)

在Python中,正则表达式模块re提供了re.compile()函数用于编译正则表达式。编译正则表达式的主要目的是为了提高匹配效率,尤其是在需要多次使用同一个正则表达式进行匹配时。

编译正则表达式的步骤如下:

  1. 导入re模块:首先需要导入Python的re模块,该模块提供了正则表达式的相关功能。

  2. 使用re.compile()函数编译正则表达式:调用re.compile()函数,并传入要编译的正则表达式作为参数。编译后的正则表达式对象将被返回。

  3. 使用编译后的正则表达式对象进行匹配:可以使用编译后的正则表达式对象进行匹配操作,比如使用match()、search()、findall()等方法进行匹配。

示例代码如下:

import re

# 编译一个匹配数字的正则表达式
pattern = re.compile(r'\d+')

# 使用编译后的正则表达式对象进行匹配
result = pattern.match('12345')
print(result.group())  # 输出: 12345

编译正则表达式的好处包括:

  • 提高匹配效率:编译后的正则表达式对象可以重复使用,不需要每次都重新解析正则表达式。

  • 简化代码:编译后的正则表达式对象可以直接调用匹配方法,简化了代码逻辑。

  • 错误检测:编译过程中会检测正则表达式是否合法,避免在运行时出现错误。

在Python中,re.compile()是一个模块级函数,用于编译正则表达式。这个函数接受一个正则表达式的字符串作为输入,并返回一个正则表达式对象,该对象可以用于在文本中进行匹配操作。

下面是关于re.compile()函数的一些重要信息:

  • 函数签名:re.compile(pattern, flags=0)

  • 参数

    • pattern:要编译的正则表达式的字符串。

    • flags:可选参数,用于指定匹配模式。例如,re.IGNORECASE可以忽略大小写。

  • 返回值:返回一个正则表达式对象,可以用于在文本中进行匹配操作。

示例代码如下:

import re

# 编译一个匹配数字的正则表达式
pattern = re.compile(r'\d+')

# 使用编译后的正则表达式对象进行匹配
result = pattern.match('12345')
print(result.group())  # 输出: 12345

通过使用re.compile()函数,可以将正则表达式编译为一个可重复使用的对象,从而提高匹配效率并简化代码逻辑。

编译标志-flags:后面的单个字母可以代替前面的单词,如re.S可以代替re.DOTALL

编译标志描述
DOTALL,S使"."点号匹配包括换行在内的所有字符
IGNORECASE,I使匹配对大小写不敏感
LOCALE,L使本地化识别()匹配.法语
MULTILINE,M多行匹配,影响和$。 适用于要匹配的文本分布在多行的情况下
VERBOSE,X能使用REs的verbose状态,使之被组织得更清晰易懂。 适用于正则表达式分布在多行的情况下

###

'RegexObject'实例有一些方法和属性,完整的列表可查阅Python Library Reference

  • match():决定RE是否在字符串刚开始的位置匹配

  • search():扫描字符串,找到这个RE匹配的位置,无论在字符串的什么位置均能找到

  • findall():找到RE匹配的所有子串,并把它们作为一个列表返回

  • finditer():找到RE匹配的所有子串,并把它们作为一个迭代器返回

注意:若未匹配到则match()和search()将返回None。若匹配成功则返回一个'MatchObject'实例对象

MatchObject实例方法:

  • group():返回被RE匹配的字符串

  • groupdict():将匹配的结果与给定的key生成一个字典并打印

  • start():返回匹配开始的位置

  • end():返回匹配结束的位置

  • span():返回一个元组包含匹配(开始,结束)的位置

解释import re
ret = re.search('(?P<id>[0-9]+)','abc1234daf@34')
print(ret.group())          # 1234
​
print(ret.groupdict())     # {'id': '1234'}
print(ret.start())          # 3
print(ret.end())            # 7
print(ret.span())           # (3, 7)

实际程序中,最常见的方法是将'MatchObject'保存在一个变量里,然后检查它是否为None。

解释import re
p = re.compile('(?P<id>[0-9]+)')
m = p.match('abc1234daf@34')
if m:
    print('Match found: ',m.group())
else:
    print('No match')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值