简述Python里面search和match的区别
很多刚学 Python 的兄弟们搞正则的时候都会被 re.search
和 re.match
这俩玩意儿搞晕。一个是“搜索”,一个是“匹配”,名字听着都挺正常的,但用起来老是出幺蛾子,最典型的问题就是:“为啥我这个正则写得没毛病,match
就是匹配不上?”
这个坑,说实话,我当年也踩过,还是线上业务上踩的。今天咱就不整那些“百度百科式”的技术文档,而是结合实际代码场景,掰扯清楚 search
和 match
的根本区别、适用场景和背后的那些“你以为你以为的就是你以为的”。
首先讲结论,直接一针见血:
-
•
re.match
是从头开始匹配,你正则再牛,它只看字符串开头,不匹配就拉倒。 -
•
re.search
是全文搜索匹配,只要某处匹配上了就行,哪怕是在字符串中间。
举个经典例子:
import retext = "Hello, my name is GPT."# 使用 match
m = re.match(r"my name", text)
print(m) # 输出 None# 使用 search
s = re.search(r"my name", text)
print(s) # 输出 <re.Match object; span=(7, 14), match='my name'>
看到了吧,match
啥都没匹配到,因为它看字符串是不是以 "my name"
开头。很显然,“Hello”才是开头,它就不干了。而 search
就不挑食,它一路从头扫到尾,扫到 "my name"
的时候眼睛一亮,就给你返回结果了。
说到这儿你可能会问,那为啥 Python 要搞两个这么像又不一样的 API 出来,是不是设计过度?
这事儿其实是有历史原因的。match
更接近传统的 C 风格正则库,要求更严格;而 search
是更贴近文本处理日常场景的选择,Python 的哲学里讲究“合理的默认行为”,所以实际开发中,search
用得多,match
用得少。
但你说 match
没用,那也不对。比如你在做某种表单验证,邮箱啊、手机号啊,要求必须从头到尾都符合格式,这时候就得用 match
,甚至更常见的是直接 fullmatch
:
# 匹配整个字符串是否是手机号
m = re.fullmatch(r"1\d{10}", "13812345678")
print(m) # 有结果m2 = re.fullmatch(r"1\d{10}", "电话是13812345678")
print(m2) # None
fullmatch
是 Python 3.4 之后才加的,它比 match
更极端:必须整个字符串都匹配得上才算。
再扯远一点,如果你用 re.compile()
预编译了正则表达式对象,其实也可以用 .match()
和 .search()
这两个方法,就像这样:
pattern = re.compile(r"\d+")print(pattern.match("123abc")) # 匹配,返回Match对象
print(pattern.match("abc123")) # 不匹配,返回Noneprint(pattern.search("123abc")) # 匹配123
print(pattern.search("abc123")) # 匹配123
所以你看,其实本质区别就在于起跑线:match
非要从字符串开头起跑,search
则是个“耐心选手”,从头跑到尾,总想碰碰运气。
那为啥有的教程讲 match
就是判断是否匹配成功?这就得小心了,不能只看表面,比如这段代码:
if re.match(r"\d+", "abc123"):print("匹配成功")
else:print("匹配失败")
你看它输出“匹配失败”,但不是说“整个字符串都不包含数字”,而是说开头不是数字。这点很多人初学时会混淆。
还有个实际开发的坑就是你写了复杂的正则,但用错了 match
和 search
,导致匹配不上,花了一下午 debug,其实就改个函数名就好了。
另外,还有一点要提醒下,别把 match
和 search
的返回值当成布尔值直接用。虽然 None
和 Match
对象确实可以这么写,但你真要用结果里的分组、位置啥的,得先判断一下:
result = re.search(r"(\d+)", "abc123")
if result:print(result.group(1)) # 输出 123
最后总结下我个人的使用习惯:
-
• 90% 的正则场景我都是用
search
,灵活,省事,适配多数情况。 -
• 做格式校验,比如身份证、手机号、日期格式,我会用
fullmatch
。 -
•
match
很少用,一般是特殊规则或者框架底层需要用才考虑。
正则这东西吧,说简单也简单,说麻烦也真麻烦,尤其当你正则写得花里胡哨,结果匹配不上,调试半天才发现函数用错了,那滋味,谁用谁知道。
所以兄弟们,搞清楚 match
和 search
的区别,能让你少踩不少坑,提升不是一点半点。下次用正则之前,不妨先想想,你到底是要从头匹配,还是全文搜索?弄清楚这个,比你多背几个正则表达式语法管用多了。
扯了这么多,反正我是觉得,Python 的 re
模块虽然好用,但 API 设计还是有点让人抓狂,尤其对新手来说,真的是“同名不同命”。要是真想让正则用得顺手,还是建议多写几段,多踩几坑,比看文档强。
就先聊到这儿,哪天有空我再来吐槽一下正则调试工具,简直是一把双刃剑...