当前位置: 首页 > article >正文

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

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

文章目录

  • Python 正则表达式详解:从基础匹配到高级应用
      • 一 功能总览
      • 二 不用正则的判断
      • 三 使用正则判断
        • 1 验证用户邮箱
        • 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()

二 不用正则的判断

# 不用正则的判断
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 验证用户邮箱
  	# 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 正则返回匹配信息
    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表示匹配到的具体字符串是什么。

四 多条件匹配

    # 同时满足多种条件,多次匹配
    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"))

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

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

六 匹配中文

 		# 匹配中文 ?爱 表示爱前面的字符可有可无
    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)

示例

 		# 扫描查找整个字符串,找到第一个模式匹配的
    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"))

八 在模式中获取特定信息

 		# 在模式中获取特定信息, 找到 *.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.Ire.IGNORECASE忽略大小写
re.Mre.MULTILINE多行模式,改变’^‘和’$'的行为
re.Sre.DOTALL点任意匹配模式,改变’.'的行为, 使".“可以匹配任意字符
re.Lre.LOCALE使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
re.Ure.UNICODE使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
re.Xre.VERBOSE详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的

示例 指定想要的模式

 		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变量顶格写,否则出现制表符,结果与预计的结果不一致。

十 使用小技巧

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

		# 更快地执行,先 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倍时间(根据不同的运行环境有不同的误差)

不提前 compile 运行时间: 0.25115203857421875
提前 compile 运行时间: 0.061614990234375

十一 完整文件示例

# 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 中运行,运行结果如下。

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


http://www.kler.cn/news/311650.html

相关文章:

  • 华为OD机试 - 构成指定长度字符串的个数(Python/JS/C/C++ 2024 E卷 100分)
  • <<编码>> 第 14 章 反馈与触发器(7)--分频器与计数器 示例电路
  • 提升工作效率,引领编程新时代
  • 【大模型开发】 迎接AI新时代:Qwen2.5发布,超越LLaMA3!本地私有化部署:如何通过一键API调用不同模型?(附源码地址)
  • 速盾:cdn一般多长时间清理下缓存?
  • 基于Ubuntu22.04的cups安装与配置
  • Servlet的继承结构
  • Java语言程序设计基础篇_编程练习题**18.31 (替换单词)
  • 网络爬虫requests访问请求过程
  • java识别图片上的文字、java中语言库tessdate的使用
  • Web APIs 第二天
  • 如何应对pcdn技术中遇到的网络安全问题?
  • Docker 进入容器并运行命令的方法
  • iOS17找不到developer mode
  • 从黎巴嫩电子通信设备爆炸看如何防范网络电子袭击
  • Python 爬虫入门 - Request 静态页面数据获取
  • 支持升降压型、升压、降压、60V的1.2MHz频率LED恒流驱动器LGS63040、LGS63042
  • 记录可编辑表格(未完整)
  • 【25.3】C++智能交友系统
  • K8s1.28 部署Dashboard获取登录信息
  • STM32 HAL freertos零基础(八)事件标志组
  • 09 Shell Scriptfor循环结构语句
  • 防爆手机+鸿蒙系统,遨游通讯筑牢工业安全基石
  • Android实现自定义下拉列表绑定数据
  • WEB 编程:使用富文本编辑器 Quill 配合 WebBroker 后端
  • Go语言grequests库并发请求的实战案例
  • vue3常用的组件间通信
  • 『功能项目』眩晕图标显示【52】
  • Mac 上哪个剪切板增强工具比较好用? 好用剪切板工具推荐
  • Cubic Eight-Puzzle(UVA-1604)