Python 正则表达式详解:从基础匹配到高级应用

Python 正则表达式详解:从基础匹配到高级应用

文章目录

  • [Python 正则表达式详解:从基础匹配到高级应用](#Python 正则表达式详解:从基础匹配到高级应用)
      • [一 功能总览](#一 功能总览)
      • [二 不用正则的判断](#二 不用正则的判断)
      • [三 使用正则判断](#三 使用正则判断)
        • [1 验证用户邮箱](#1 验证用户邮箱)
        • [2 正则返回匹配信息](#2 正则返回匹配信息)
      • [四 多条件匹配](#四 多条件匹配)
      • [五 按类型匹配](#五 按类型匹配)
      • [六 匹配中文](#六 匹配中文)
      • [七 查找替换等功能](#七 查找替换等功能)
      • [八 在模式中获取特定信息](#八 在模式中获取特定信息)
      • [九 多模式匹配](#九 多模式匹配)
      • [十 使用小技巧](#十 使用小技巧)
      • [十一 完整文件示例](#十一 完整文件示例)
      • [十二 源码地址](#十二 源码地址)

正则表达式(Regex)是一种用于字符串匹配的强大工具,广泛应用于各类开发语言中。本篇详细介绍了 Python 中正则表达式的基本操作和进阶应用。内容涵盖了简单的字符串匹配、复杂的多条件匹配、按类型匹配和中文字符处理等。你将学习如何使用 re 模块中的 compile()search()match()findall()sub() 等函数进行文本查找、替换和分割。此外,文章还介绍了模式匹配的技巧以及如何通过编译优化执行效率。无论你是初学者还是进阶用户,这篇文章都将帮助你全面掌握正则表达式的强大功能。

正则表达式在各大开发语言中都是通用的,一式在手天下我有。这一节主要涉及的功能:

一 功能总览

编译为正则的对象 正则返回匹配信息 中文字符串编码 查找替换等
re.compile() re.search() string.encode() re.search()
ptn.search() re.match()
re.findall()
re.finditer()
re.split()
re.sub()
re.subn()

二 不用正则的判断

python 复制代码
# 不用正则的判断
pattern1 = "file"
pattern2 = "files"
string = "the file is in the folder"
print("file in string", pattern1 in string)
print("files in string", pattern2 in string)
print()

三 使用正则判断

当判断相对复杂的字符串信息时,建议使用正则,比如匹配一个邮箱

1 验证用户邮箱
python 复制代码
  	# import re  
  	ptn = re.compile(r"\w+?@\w+?\.com")

    matched = ptn.search("mofan@mofanpy.com")
    print("mofan@mofanpy.com is a valid email:", matched)
    matched = ptn.search("mofan@mofanpy+com")
    print("mofan@mofanpy+com is a valid email:", matched)
2 正则返回匹配信息
python 复制代码
    matched = re.search(r"\w+?@\w+?\.com", "mofan@mofanpy.com")
    print("mofan@mofanpy.com:", matched)
    # mofan@mofanpy.com: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'>
    # 打印的参数中 span 是从哪一位到哪一位(0, 17),match表示找到的具体字符串又是什么。
    matched = re.search(r"\w+?@\w+?\.com", "the email is mofan@mofanpy.com.")
    print("the email is mofan@mofanpy.com:", matched)
    # 一个简单的例子,r"xxx" 为固定写法
    match = re.search(r"run", "I run to you")
    print(match)
    print(match.span())
    print(match.group())

mofan@mofanpy.com: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'> 的打印信息中, span 是🈯️从哪一位到哪一位(0, 17),match表示匹配到的具体字符串是什么。

四 多条件匹配

python 复制代码
    # 同时满足多种条件,多次匹配
    print(re.search(r"ran", "I run to you"))
    print(re.search(r"run", "I run to you"))
    # 同时满足多种条件,一次匹配, | 就代表或者; [au] 中间字母是 a 或者 u
    print(re.search(r"ran|run", "I run to you"))
    print(re.search(r"r[au]n", "I run to you"))
    # 同时满足多种条件,前后都是固定的,同时满足多个字符的不同匹配,比如找到 find 和 found
    print(re.search(r"f(ou|i)nd", "I find you"))
    print(re.search(r"f(ou|i)nd", "I found you"))
    print()

五 按类型匹配

通用正则表达式

特定标识 含义 范围
\d 任何数字 [0-9]
\D 不是数字的
\s 任何空白字符 [ \t\n\r\f\v]
\S 空白字符以外的
\w 任何大小写字母,数字和 _ [a-zA-Z0-9_]
\W \w 以外的
\b 匹配一个单词边界 比如 er\b 可以匹配 never 中的 er, 但不能匹配 verb 中的 er
\B 匹配非单词边界 比如 er\B 能匹配 verb 中的 er, 但不能匹配 never 中的 er
\ 强制匹配 \
. 匹配任何字符 (除了 \n)
? 前面的模式可有可无
* 重复零次或多次
+ 重复一次或多次
{n,m} 重复 n 至 m 次
{n} 重复 n 次
+? 非贪婪,最小方式匹配 +
*? 非贪婪,最小方式匹配 *
?? 非贪婪,最小方式匹配 ?
^ 匹配一行开头,在 re.M 下,每行开头都匹配
$ 匹配一行结尾,在 re.M 下,每行结尾都匹配
\A 匹配最开始,在 re.M 下,也从文本最开始
\B 匹配最结尾,在 re.M 下,也从文本最结尾

示例

python 复制代码
    # 匹配邮箱 ,\w 表示任意的字母和数字下划线。 +? 表示让 \w 至少匹配 1 次
    re.search(r"\w+?@\w+?\.com", "mofan@mofanpy.com")
    # 匹配手机号
    # \d{8} 表示任意的数字,重复8遍。
    print(re.search(r"138\d{8}", "13812345678"))
    print(re.search(r"138\d{8}", "138123456780000"))

\w+?@\w+?\.com:\w 表示任意的字母和数字下划线。 +? 表示让 \w 至少匹配 1 次。

\d{8}:表示任意的数字,重复8遍。

六 匹配中文

python 复制代码
 		# 匹配中文 ?爱 表示爱前面的字符可有可无
    print(re.search(r"不?爱", "我爱你"))
    # 匹配中文 不?爱 表示爱前面的字符可有可无,有不就匹配
    print(re.search(r"不?爱", "我不爱你"))
    # 匹配中文 不.*?爱 表示 不 必须匹配, .* 匹配任何字符 (除了 \n)重复零次或多次, 爱前面的字符可有可无
    print(re.search(r"不.*?爱", "我不是很爱你"))
    print()
    # 匹配全部汉字,汉字是用 Unicode 来表示的,把汉字变成 Unicode
    print("中".encode("unicode-escape"))
    print(re.search(r"[\u4e00-\u9fa5]+", "我爱编码,Python。"))
    # 匹配全部汉字,识别中文标点,比如 [!?。,¥【】「」]
    print(re.search(r"[\u4e00-\u9fa5!?。,¥【】「」]+", "我爱编码。编码让人「神清气爽」!haha"))

七 查找替换等功能

功能说明

功能 说明 举例
re.search() 扫描查找整个字符串,找到第一个模式匹配的 re.search(rrun, I run to you) > 'run'
re.match() 从字符的最开头匹配,找到第一个模式匹配的即使用 re.M 多行匹配,也是从最最开头开始匹配 re.match(rrun, I run to you) > None
re.findall() 返回一个不重复的 pattern 的匹配列表 re.findall(rr[ua]n, I run to you. you ran to him) > ['run', 'ran']
re.finditer() 和 findall 一样,只是用迭代器的方式使用 for item in re.finditer(rr[ua]n, I run to you. you ran to him):
re.split() 用正则分开字符串 re.split(rr[ua]n, I run to you. you ran to him) > ['I ', ' to you. you ', ' to him']
re.sub() 用正则替换字符 re.sub(rr[ua]n, jump, I run to you. you ran to him) > 'I jump to you. you jump to him'
re.subn() 和 sub 一样,额外返回一个替代次数 re.subn(rr[ua]n, jump, I run to you. you ran to him) > ('I jump to you. you jump to him', 2)

示例

python 复制代码
 		# 扫描查找整个字符串,找到第一个模式匹配的
    print("search:", re.search(r"run", "I run to you"))
    # 从字符的最开头匹配,找到第一个模式匹配的即使用 re.M 多行匹配,也是从最最开头开始匹配
    print("match:", re.match(r"run", "I run to you"))
    # 返回一个不重复的 pattern 的匹配列表
    print("findall:", re.findall(r"r[ua]n", "I run to you. you ran to him"))
    # 和 findall 一样,只是用迭代器的方式使用
    for i in re.finditer(r"r[ua]n", "I run to you. you ran to him"):
        print("finditer:", i)
    # 用正则分开字符串
    print("split:", re.split(r"r[ua]n", "I run to you. you ran to him"))
    # 用正则替换字符
    print("sub:", re.sub(r"r[ua]n", "jump", "I run to you. you ran to him"))
    # 和 sub 一样,额外返回一个替代次数
    print("subn:", re.subn(r"r[ua]n", "jump", "I run to you. you ran to him"))

八 在模式中获取特定信息

python 复制代码
 		# 在模式中获取特定信息, 找到 *.jpg 图片文件,而且只返回去掉 .jpg 之后的纯文件名
    found = []
    for i in re.finditer(r"[\w-]+?\.jpg", "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"):
        found.append(re.sub(r".jpg", "", i.group()))
    print(found)
    print()
    # () 提取匹配的字符串:要截取返回的位置,直接返回括号里的内容。
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    print("without ():", re.findall(r"[\w-]+?\.jpg", string))
    print("with ():", re.findall(r"([\w-]+?)\.jpg", string))
    print()
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.finditer(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
    for file in match:
        print("matched string:", file.group(0), ",year:", file.group(1), ", month:", file.group(2), ", day:",
              file.group(3))
    print()
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.findall(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
    for file in match:
        print("year:", file[0], ", month:", file[1], ", day:", file[2])
    print()
    # 索引名字
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.finditer(r"(?P<y>\d+?)-(?P<m>\d+?)-(?P<d>\d+?)\.jpg", string)
    for file in match:
        print("matched string:", file.group(0),
              ", year:", file.group("y"),
              ", month:", file.group("m"),
              ", day:", file.group("d"))

九 多模式匹配

常用的模式

模式 全称 说明
re.I re.IGNORECASE 忽略大小写
re.M re.MULTILINE 多行模式,改变'^'和'$'的行为
re.S re.DOTALL 点任意匹配模式,改变'.'的行为, 使"."可以匹配任意字符
re.L re.LOCALE 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
re.U re.UNICODE 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
re.X re.VERBOSE 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的

示例 指定想要的模式

python 复制代码
 		ptn, string = r"r[ua]n", "I Ran to you"
    print("without re.I:", re.search(ptn, string))
    print("with re.I:", re.search(ptn, string, flags=re.I))
    print()

    ptn02 = r"^ran"
    # 多行字符串匹配得顶格写,否则前面有空格或缩进,无法匹配, ^ 要求 "ran" 必须在新行的最开始处。
    string02 = """I
ran to you"""
    print("without re.M:", re.search(ptn02, string02))
    print("with re.M:", re.search(ptn02, string02, flags=re.M))
    print("with re.M and match:", re.match(ptn02, string02, flags=re.M))

    print()
    ptn03 = r"^ran"
    string03 = """I
Ran to you"""
    print("with re.M and re.I:", re.search(ptn03, string03, flags=re.M | re.I))

    print()
    string04 = """I
Ran to you"""
    print(re.search(r"(?im)^ran", string04))
    print()

注:这里的string02,string03,string04变量顶格写,否则出现制表符,结果与预计的结果不一致。

十 使用小技巧

写法不同执行效率不同,更快地执行正则。

python 复制代码
		# 更快地执行,先 compile 正则

    n = 1000000
    # 不提前 compile
    t0 = time.time()
    for _ in range(n):
        re.search(r"ran", "I ran to you")
    t1 = time.time()
    print("不提前 compile 运行时间:", t1 - t0)

    # 先做 compile
    ptn = re.compile(r"ran")
    for _ in range(n):
        ptn.search("I ran to you")
    print("提前 compile 运行时间:", time.time() - t1) 

执行时间对比,不提前 compile 比 提前 compile 多了4倍时间(根据不同的运行环境有不同的误差)

nginx 复制代码
不提前 compile 运行时间: 0.25115203857421875
提前 compile 运行时间: 0.061614990234375

十一 完整文件示例

python 复制代码
# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import re
import time


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press ⌘F8 to toggle the breakpoint.
    # 正则表达式 在各大开发语言中都是通用的,一式在手天下我有
    # 这一节主要涉及到的功能:
    # 不用正则的判断
    # re.compile()
    # ptn.search()
    # 正则给额外信息
    # re.search()
    # 中文
    # string.encode()
    # 查找替换等更多功能
    # re.search()
    # re.match()
    # re.findall()
    # re.finditer()
    # re.split()
    # re.sub()
    # re.subn()

    # 不用正则的判断
    pattern1 = "file"
    pattern2 = "files"
    string = "the file is in the folder"
    print("file in string", pattern1 in string)
    print("files in string", pattern2 in string)
    print()
    # 验证用户输入的信息是否是邮箱
    ptn = re.compile(r"\w+?@\w+?\.com")

    matched = ptn.search("mofan@mofanpy.com")
    print("mofan@mofanpy.com is a valid email:", matched)
    matched = ptn.search("mofan@mofanpy+com")
    print("mofan@mofanpy+com is a valid email:", matched)
    print()
    # 正则给额外信息
    matched = re.search(r"\w+?@\w+?\.com", "mofan@mofanpy.com")
    print("mofan@mofanpy.com:", matched)
    # mofan@mofanpy.com: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'>
    # 打印的参数中 span 是从哪一位到哪一位(0, 17),match表示找到的具体字符串又是什么。
    matched = re.search(r"\w+?@\w+?\.com", "the email is mofan@mofanpy.com.")
    print("the email is mofan@mofanpy.com:", matched)
    # 一个简单的例子,r"xxx" 为固定写法
    match = re.search(r"run", "I run to you")
    print(match)
    print(match.span())
    print(match.group())

    # 同时满足多种条件,多次匹配
    print(re.search(r"ran", "I run to you"))
    print(re.search(r"run", "I run to you"))
    # 同时满足多种条件,一次匹配, | 就代表或者; [au] 中间字母是 a 或者 u
    print(re.search(r"ran|run", "I run to you"))
    print(re.search(r"r[au]n", "I run to you"))
    # 同时满足多种条件,前后都是固定的,同时满足多个字符的不同匹配,比如找到 find 和 found
    print(re.search(r"f(ou|i)nd", "I find you"))
    print(re.search(r"f(ou|i)nd", "I found you"))
    print()
    # 按类型匹配,通用匹配方式
    # 特定标识	含义	范围
    # \d	任何数字	[0-9]
    # \D	不是数字的
    # \s	任何空白字符	[ \t\n\r\f\v]
    # \S	空白字符以外的
    # \w	任何大小写字母,数字和 _	[a-zA-Z0-9_]
    # \W	\w 以外的
    # \b	匹配一个单词边界	比如 er\b 可以匹配 never 中的 er,但不能匹配 verb 中的 er
    # \B	匹配非单词边界	比如 er\B 能匹配 verb 中的 er,但不能匹配 never 中的 er
    # \\	强制匹配 \
    # .	匹配任何字符 (除了 \n)
    # ?	前面的模式可有可无
    # *	重复零次或多次
    # +	重复一次或多次
    # {n,m}	重复 n 至 m 次
    # {n}	重复 n 次
    # +?	非贪婪(匹配尽可能少的字符),最小方式匹配 +
    # *?	非贪婪(匹配尽可能少的字符),最小方式匹配 *
    # ??	非贪婪(匹配尽可能少的字符),最小方式匹配 ?
    # ^	匹配一行开头,在 re.M 下,每行开头都匹配
    # $	匹配一行结尾,在 re.M 下,每行结尾都匹配
    # \A	匹配最开始,在 re.M 下,也从文本最开始
    # \B	匹配最结尾,在 re.M 下,也从文本最结尾

    # 匹配邮箱 ,\w 表示任意的字母和数字下划线。 +? 表示让 \w 至少匹配 1 次
    re.search(r"\w+?@\w+?\.com", "mofan@mofanpy.com")
    # 匹配手机号
    # \d{8} 表示任意的数字,重复8遍。
    print(re.search(r"138\d{8}", "13812345678"))
    print(re.search(r"138\d{8}", "138123456780000"))
    print()
    # 匹配中文 ?爱 表示爱前面的字符可有可无
    print(re.search(r"不?爱", "我爱你"))
    # 匹配中文 不?爱 表示爱前面的字符可有可无,有不就匹配
    print(re.search(r"不?爱", "我不爱你"))
    # 匹配中文 不.*?爱 表示 不 必须匹配, .* 匹配任何字符 (除了 \n)重复零次或多次, 爱前面的字符可有可无
    print(re.search(r"不.*?爱", "我不是很爱你"))
    print()
    # 匹配全部汉字,汉字是用 Unicode 来表示的,把汉字变成 Unicode
    print("中".encode("unicode-escape"))
    print(re.search(r"[\u4e00-\u9fa5]+", "我爱编码,Python。"))
    # 匹配全部汉字,识别中文标点,比如 [!?。,¥【】「」]
    print(re.search(r"[\u4e00-\u9fa5!?。,¥【】「」]+", "我爱编码。编码让人「神清气爽」!haha"))
    print()

    # 查找替换等更多功能
    # 扫描查找整个字符串,找到第一个模式匹配的
    print("search:", re.search(r"run", "I run to you"))
    # 从字符的最开头匹配,找到第一个模式匹配的即使用 re.M 多行匹配,也是从最最开头开始匹配
    print("match:", re.match(r"run", "I run to you"))
    # 返回一个不重复的 pattern 的匹配列表
    print("findall:", re.findall(r"r[ua]n", "I run to you. you ran to him"))
    # 和 findall 一样,只是用迭代器的方式使用
    for i in re.finditer(r"r[ua]n", "I run to you. you ran to him"):
        print("finditer:", i)
    # 用正则分开字符串
    print("split:", re.split(r"r[ua]n", "I run to you. you ran to him"))
    # 用正则替换字符
    print("sub:", re.sub(r"r[ua]n", "jump", "I run to you. you ran to him"))
    # 和 sub 一样,额外返回一个替代次数
    print("subn:", re.subn(r"r[ua]n", "jump", "I run to you. you ran to him"))
    print()

    # 在模式中获取特定信息, 找到 *.jpg 图片文件,而且只返回去掉 .jpg 之后的纯文件名
    found = []
    for i in re.finditer(r"[\w-]+?\.jpg", "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"):
        found.append(re.sub(r".jpg", "", i.group()))
    print(found)
    print()
    # () 提取匹配的字符串:要截取返回的位置,直接返回括号里的内容。
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    print("without ():", re.findall(r"[\w-]+?\.jpg", string))
    print("with ():", re.findall(r"([\w-]+?)\.jpg", string))
    print()
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.finditer(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
    for file in match:
        print("matched string:", file.group(0), ",year:", file.group(1), ", month:", file.group(2), ", day:",
              file.group(3))
    print()
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.findall(r"(\d+?)-(\d+?)-(\d+?)\.jpg", string)
    for file in match:
        print("year:", file[0], ", month:", file[1], ", day:", file[2])
    print()
    # 索引名字
    string = "I have 2021-02-01.jpg, 2021-02-02.jpg, 2021-02-03.jpg"
    match = re.finditer(r"(?P<y>\d+?)-(?P<m>\d+?)-(?P<d>\d+?)\.jpg", string)
    for file in match:
        print("matched string:", file.group(0),
              ", year:", file.group("y"),
              ", month:", file.group("m"),
              ", day:", file.group("d"))
    print()
    # 多模式匹配
    # re.I 忽略大小写
    # re.M 多行模式,改变'^'和'$'的行为,标志意味着 ^ 和 $ 分别匹配输入字符串的开始处和结束处,以及每一行的开始和结束处。
    # re.S 点任意匹配模式,改变'.'的行为, 使"."可以匹配任意字符
    # re.L 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
    # re.U 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
    # re.X 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的
    ptn, string = r"r[ua]n", "I Ran to you"
    print("without re.I:", re.search(ptn, string))
    print("with re.I:", re.search(ptn, string, flags=re.I))
    print()

    ptn02 = r"^ran"
    # 多行字符串匹配得顶格写,否则前面有空格或缩进,无法匹配, ^ 要求 "ran" 必须在新行的最开始处。
    string02 = """I
ran to you"""
    print("without re.M:", re.search(ptn02, string02))
    print("with re.M:", re.search(ptn02, string02, flags=re.M))
    print("with re.M and match:", re.match(ptn02, string02, flags=re.M))

    print()
    ptn03 = r"^ran"
    string03 = """I
Ran to you"""
    print("with re.M and re.I:", re.search(ptn03, string03, flags=re.M | re.I))

    print()
    string04 = """I
Ran to you"""
    print(re.search(r"(?im)^ran", string04))
    print()

    # 更快地执行,先 compile 正则

    n = 1000000
    # 不提前 compile
    t0 = time.time()
    for _ in range(n):
        re.search(r"ran", "I ran to you")
    t1 = time.time()
    print("不提前 compile 运行时间:", t1 - t0)

    # 先做 compile
    ptn = re.compile(r"ran")
    for _ in range(n):
        ptn.search("I ran to you")
    print("提前 compile 运行时间:", time.time() - t1)


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('正则表达式')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。

nginx 复制代码
Hi, 正则表达式
file in string True
files in string False

mofan@mofanpy.com is a valid email: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'>
mofan@mofanpy+com is a valid email: None

mofan@mofanpy.com: <re.Match object; span=(0, 17), match='mofan@mofanpy.com'>
the email is mofan@mofanpy.com: <re.Match object; span=(13, 30), match='mofan@mofanpy.com'>
<re.Match object; span=(2, 5), match='run'>
(2, 5)
run
None
<re.Match object; span=(2, 5), match='run'>
<re.Match object; span=(2, 5), match='run'>
<re.Match object; span=(2, 5), match='run'>
<re.Match object; span=(2, 6), match='find'>
<re.Match object; span=(2, 7), match='found'>

<re.Match object; span=(0, 11), match='13812345678'>
<re.Match object; span=(0, 11), match='13812345678'>

<re.Match object; span=(1, 2), match='爱'>
<re.Match object; span=(1, 3), match='不爱'>
<re.Match object; span=(1, 5), match='不是很爱'>

b'\\u4e2d'
<re.Match object; span=(0, 4), match='我爱编码'>
<re.Match object; span=(0, 16), match='我爱编码。编码让人「神清气爽」!'>

search: <re.Match object; span=(2, 5), match='run'>
match: None
findall: ['run', 'ran']
finditer: <re.Match object; span=(2, 5), match='run'>
finditer: <re.Match object; span=(18, 21), match='ran'>
split: ['I ', ' to you. you ', ' to him']
sub: I jump to you. you jump to him
subn: ('I jump to you. you jump to him', 2)

['2021-02-01', '2021-02-02', '2021-02-03']

without (): ['2021-02-01.jpg', '2021-02-02.jpg', '2021-02-03.jpg']
with (): ['2021-02-01', '2021-02-02', '2021-02-03']

matched string: 2021-02-01.jpg ,year: 2021 , month: 02 , day: 01
matched string: 2021-02-02.jpg ,year: 2021 , month: 02 , day: 02
matched string: 2021-02-03.jpg ,year: 2021 , month: 02 , day: 03

year: 2021 , month: 02 , day: 01
year: 2021 , month: 02 , day: 02
year: 2021 , month: 02 , day: 03

matched string: 2021-02-01.jpg , year: 2021 , month: 02 , day: 01
matched string: 2021-02-02.jpg , year: 2021 , month: 02 , day: 02
matched string: 2021-02-03.jpg , year: 2021 , month: 02 , day: 03

without re.I: None
with re.I: <re.Match object; span=(2, 5), match='Ran'>

without re.M: None
with re.M: <re.Match object; span=(2, 5), match='ran'>
with re.M and match: None

with re.M and re.I: <re.Match object; span=(2, 5), match='Ran'>

<re.Match object; span=(2, 5), match='Ran'>

不提前 compile 运行时间: 0.25180697441101074
提前 compile 运行时间: 0.06008291244506836

十二 源码地址

代码地址:

国内看 Gitee正则表达式.py

国外看 GitHub正则表达式.py

引用 莫烦 Python

相关推荐
Hello-Brand8 分钟前
Java核心知识体系10-线程管理
java·高并发·多线程·并发·多线程模型·线程管理
小han的日常14 分钟前
pycharm分支提交操作
python·pycharm
乐悠小码14 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
史努比.16 分钟前
Pod控制器
java·开发语言
2的n次方_19 分钟前
二维费用背包问题
java·算法·动态规划
皮皮林55119 分钟前
警惕!List.of() vs Arrays.asList():这些隐藏差异可能让你的代码崩溃!
java
莳光.19 分钟前
122、java的LambdaQueryWapper的条件拼接实现数据sql中and (column1 =1 or column1 is null)
java·mybatis
程序猿麦小七24 分钟前
基于springboot的景区网页设计与实现
java·spring boot·后端·旅游·景区
weisian15131 分钟前
认证鉴权框架SpringSecurity-2--重点组件和过滤器链篇
java·安全
蓝田~32 分钟前
SpringBoot-自定义注解,拦截器
java·spring boot·后端