跳到正文
效率工具实用笔记关于本站
效率工具

检查整段文本是否符合格式:fullmatch 与 search 的区别

约 7 分钟阅读AI 辅助整理

用自建 ASCII 编号示例说明:fullmatch 要求整段完全匹配,search 只找第一个出现位置。给出原始字符串写法、边界判断和结果核对方法,不涉及复杂回溯模式。

本文要点

  1. 编号模式里会用到反斜杠,比如用 \d 表示数字

  2. 编号模式的边界由三部分共同决定,缺一项都可能放过不该放过的字符串

  3. 两个函数都返回 Match 对象或 None,判断方式一致:用 if 判断真假即可,不要直接比较字符串

检查整段文本是否符合格式:fullmatch 与 search 的区别的知识要点示意图
依据已审核正文摘取要点制作的示意图,非实物照片;请结合正文中的条件与范围阅读。要点摘自已审核正文;完整条件与说明见正文。查看高清图解 ↗
本文目录

先分清你要问的是“整段合规”还是“里面有”

假设你在练习目录里维护一份自建编号清单,每行是一个短编号,比如 A-001、B-042。你想写一段检查代码,判断某个字符串是不是“一个完整编号”。

这时先回答一个问题:你要检查的是整段字符串从头到尾都符合编号格式,还是只要字符串里任意位置出现一个编号就算通过。

这两个问题对应两个不同的函数。按 Python 官方 re 文档的说明,re.fullmatch(pattern, string, flags=0) 在“整个字符串匹配该模式”时返回一个 Match 对象,否则返回 None;re.search(pattern, string, flags=0) 则扫描字符串,寻找模式产生匹配的第一个位置,返回对应的 Match,找不到任何位置匹配时返回 None。

所以判断标准很简单:整段合规用 fullmatch,找“里面有没有”用 search。本文只处理短自建 ASCII 编号,所有字符串都是练习用的自建示例,不涉及真实业务数据。动手前建议在练习目录里新建脚本,例如 exercise/re_check.py,不要拿正在用的数据直接试。

用原始字符串写编号模式,避免反斜杠被二次转义

编号模式里会用到反斜杠,比如用 \d 表示数字。这里有一个容易踩的坑:Python 字符串字面量本身也把反斜杠当转义符。

按 re 文档的说明,正则表达式用反斜杠表示特殊形式,这和 Python 字符串字面量里反斜杠的用法冲突;解决办法是使用原始字符串写法,也就是在字符串前加 r,这样反斜杠不会被特殊处理。文档举的例子是:r"\n" 是两个字符,反斜杠和 n;而 "\n" 是一个字符,换行。

对编号检查来说,模式可以写成 r"[A-Z]-\d{3}"。这里 [A-Z] 表示一个大写字母,- 是字面连字符,\d{3} 表示恰好三位数字。

下面这段只操作内存里的自建字符串,不读写文件:

import re

pattern = r"[A-Z]-\d{3}"

print(re.fullmatch(pattern, "A-001"))   # 匹配
print(re.fullmatch(pattern, "A-001X"))  # None
print(re.search(pattern, "编号 A-001 已登记"))  # 匹配

注意 fullmatch 对 "A-001X" 返回 None,因为整段多了一个 X;search 对带前后文字的字符串仍然能匹配,因为它只要求某个位置出现编号。

边界怎么定:字符集、量词和整段长度

编号模式的边界由三部分共同决定,缺一项都可能放过不该放过的字符串。

第一是字符集。[A-Z] 只匹配一个大写 ASCII 字母。如果你写成 [A-Za-z],小写字母也会通过;如果你写成 \w,按文档说明,在 Unicode 模式下 \w 会匹配 Unicode 字母数字和下划线,范围比你想的宽。要限定 ASCII,可以配合 re.ASCII 标志,文档说明它让 \w、\d、\s 等只做 ASCII 匹配。

第二是量词。\d{3} 表示恰好三位数字。文档说明 {m} 要求恰好 m 次重复,少了整个表达式不匹配;{m,n} 表示 m 到 n 次,尽量多匹配。用 {3} 而不是 +,是为了不让 A-1 或 A-12345 通过。

第三是整段长度。这正是 fullmatch 的价值:它要求整个字符串匹配,所以即使模式本身只描述“字母-三位数字”,多出来的字符也会导致失败。search 没有这个约束,它只报告第一个匹配位置。

一个自建对照(以下为编辑设计的示例,不是实测记录):

- "A-001":fullmatch 通过,search 也通过。

- "A-001X":fullmatch 不通过,search 通过(匹配到 A-001 这一段)。

- "XA-001":fullmatch 不通过,search 通过。

如果你的业务规则是“这一行必须整体是一个编号”,就必须用 fullmatch;用 search 会把带前后缀的字符串也判为通过。

检查结果:Match 对象和 None 分别代表什么

两个函数都返回 Match 对象或 None,判断方式一致:用 if 判断真假即可,不要直接比较字符串。

Match 对象可以取匹配到的文本。文档说明 m.group(0) 返回整个匹配。对 fullmatch 来说,匹配文本就是整段字符串;对 search 来说,匹配文本只是命中的那一段。

m = re.search(pattern, "编号 A-001 已登记")
if m:
    print(m.group(0))  # A-001

这里有一个容易误判的点:文档特别说明,search 找不到匹配时返回 None,这和“在某个位置找到零长度匹配”不同。所以不要用“返回值是不是空字符串”来判断,None 才是没找到。

另一个核对习惯:把模式和输入都打印出来。很多“检查不通过”其实是模式写错或输入里混了空格、全角字符。先看输入的实际内容,再改模式。

出错时怎么排查:从输入、模式、函数三处依次看

检查结果不符合预期时,按下面顺序排查,每一步只改一个变量。

1. 看输入。字符串里有没有前后空格、换行、全角字母或全角数字。fullmatch 要求整段匹配,一个多余空格就会导致 None。

2. 看模式。确认用了原始字符串;确认字符集和量词写对了;确认连字符的位置,在字符集里 - 放在首尾或转义才是字面连字符。

3. 看函数。问自己:我要的是整段合规还是存在即可。整段合规用 fullmatch,存在即可用 search。两者不能互相替代。

4. 看类型。文档说明 Unicode 字符串和 8 位字符串不能混用:不能用 bytes 模式去匹配 str 字符串,反之亦然。如果输入是从文件按二进制读出来的 bytes,就要统一类型。

一个自建练习:把 "A-001"、"A-001X"、" A-001" 三个字符串分别交给 fullmatch 和 search,记录各自结果,再对照上面的对照表。这样能直观看到边界差异。

适用限制:这套方法只覆盖短 ASCII 编号

本文的范围限定在短自建 ASCII 编号,比如一个大写字母加连字符加三位数字。超出这个范围的情况,需要另行核对资料,本文不展开。

几点限制说明:

- 不涉及复杂模式。带嵌套量词、多层可选分支的模式容易产生大量回溯,本文不设计这类模式,也不给性能结论。

- 不涉及 Unicode 编号。如果编号里含中文、全角字符或其他 Unicode 字符,字符集和标志都要重新考虑,本文的示例不适用。

- 不涉及文件读写和系统修改。示例只操作内存中的自建字符串,脚本放在练习目录,不删除、不覆盖任何现有数据。

- 不把匹配结果当作数据校验的最终结论。fullmatch 通过只说明字符串符合你写的模式,不说明编号在业务上真实存在。

参考资料:Python 官方 re 模块文档,https://docs.python.org/3/library/re.html。

观看知识要点视频 18 秒

18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。

参考资料

以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。

请结合原始资料的适用条件阅读。

返回效率工具 →