re.search() 是什么?
re.search() 函数用于在字符串的任意位置搜索第一个匹配正则表达式模式的子串,如果找到匹配,它返回一个匹配对象(Match Object);如果找不到,则返回 None。

它的核心特点是:只要字符串中 存在 一个匹配项,就会返回,并且只返回第一个找到的。
函数语法
re.search(pattern, string, flags=0)
参数说明:
pattern(必需): 你要搜索的正则表达式模式,这是一个字符串,描述了你要查找的文本规则。string(必需): 你要在其中进行搜索的目标字符串。flags(可选): 用于修改正则表达式匹配行为的标志。re.IGNORECASE或re.I: 忽略大小写。re.MULTILINE或re.M: 多行模式,影响^和 的行为。re.DOTALL或re.S: 使 匹配包括换行符在内的所有字符。
返回值:
- 匹配对象 (
Match Object): 如果找到匹配项。 None: 如果没有找到匹配项。
匹配对象 (Match Object) 的常用方法
当 re.search() 找到匹配后,返回的匹配对象包含了丰富的信息,你可以通过以下方法来获取:
.group(): 返回匹配到的字符串,这是最常用的方法。- 如果模式中有分组(使用圆括号 ),
.group(1)返回第一个分组的内容,.group(2)返回第二个,以此类推。.group(0)或.group()返回整个匹配的字符串。
- 如果模式中有分组(使用圆括号 ),
.start(): 返回匹配字符串在原始字符串中的起始索引。.end(): 返回匹配字符串在原始字符串中的结束索引(结束索引是不包含的)。.span(): 返回一个元组(start, end),包含匹配的起始和结束位置。
详细示例
示例 1:基础用法
import re
text = "Hello, my phone number is 123-456-7890. Please call me."
pattern = r"\d{3}-\d{3}-\d{4}" # 匹配 US 电话号码格式
# 使用 re.search 进行搜索
match = re.search(pattern, text)
if match:
print("找到了匹配的号码!")
# .group() 获取匹配到的文本
print(f"匹配的号码是: {match.group()}")
# .span() 获取匹配的位置
print(f"号码在文本中的位置是: {match.span()}")
# .start() 和 .end() 分别获取起始和结束位置
print(f"起始索引: {match.start()}, 结束索引: {match.end()}")
else:
print("没有找到匹配的号码。")
输出:
找到了匹配的号码!
匹配的号码是: 123-456-7890
号码在文本中的位置是: (20, 32)
起始索引: 20, 结束索引: 32
示例 2:使用分组提取信息
假设我们想从匹配的号码中分别提取区号、前缀和后四位。

import re
text = "My contact is 123-456-7890."
pattern = r"(\d{3})-(\d{3})-(\d{4})" # 使用 () 创建三个分组
match = re.search(pattern, text)
if match:
print("找到了匹配的号码!")
# group(0) 是整个匹配
print(f"完整匹配: {match.group(0)}")
# group(1) 是第一个分组 (区号)
print(f"区号: {match.group(1)}")
# group(2) 是第二个分组 (前缀)
print(f"前缀: {match.group(2)}")
# group(3) 是第三个分组 (后四位)
print(f"后四位: {match.group(3)}")
else:
print("没有找到匹配的号码。")
输出:
找到了匹配的号码!
完整匹配: 123-456-7890
区号: 123
前缀: 456
后四位: 7890
示例 3:处理不匹配的情况
import re
text = "This is a sentence without any numbers."
pattern = r"\d+" # 匹配一个或多个数字
match = re.search(pattern, text)
if match:
print(f"找到了数字: {match.group()}")
else:
print("没有找到任何数字。") # 这行代码会被执行
输出:
没有找到任何数字。
示例 4:使用标志(flags)
import re
text = "Python is a great language. PYTHON is powerful."
pattern = r"python" # 模式是小写
# 不使用 flags
match1 = re.search(pattern, text)
print(f"不区分大小写搜索: {match1}") # 输出 None
# 使用 re.IGNORECASE 标志
match2 = re.search(pattern, text, re.IGNORECASE)
if match2:
print(f"使用 IGNORECASE 标志搜索: 找到了 '{match2.group()}'")
输出:
不区分大小写搜索: None
使用 IGNORECASE 标志搜索: 找到了 'Python'
re.search() vs. re.match() vs. re.findall()
这是一个非常常见的混淆点,理解它们的区别很重要。

| 函数 | 搜索范围 | 返回值 | 何时使用 |
|---|---|---|---|
re.search() |
整个字符串的任意位置 | 第一个匹配的匹配对象 或 None |
当你只想知道字符串中是否存在某个模式,并且只需要第一个结果时,这是最灵活的搜索方式。 |
re.match() |
字符串的开头 | 第一个匹配的匹配对象 或 None |
当你只想检查字符串是否以某个模式开头时,如果模式不在开头,它立即返回 None,不会继续搜索。 |
re.findall() |
整个字符串 | 一个列表,包含所有匹配到的子串 | 当你需要找到字符串中所有匹配的子串时,如果模式中有分组,它只返回分组的内容。 |
re.search() vs. re.match() 示例
import re
text = "123 is a number."
# re.match 只从开头匹配
match_obj = re.match(r"\d+", text)
print(f"re.match 结果: {match_obj.group()}") # 成功,因为字符串以数字开头
text2 = "The number is 123."
match_obj2 = re.match(r"\d+", text2)
print(f"re.match 结果: {match_obj2}") # 失败,返回 None,因为字符串不以数字开头
# re.search 在整个字符串中搜索
search_obj = re.search(r"\d+", text2)
print(f"re.search 结果: {search_obj.group()}") # 成功,因为它在字符串中间找到了数字
输出:
re.match 结果: 123
re.match 结果: None
re.search 结果: 123
re.search()是你工具箱里最强大的搜索工具之一。- 它的核心功能是:在整个字符串中查找第一个匹配项。
- 务必检查返回值是否为
None,以避免在未找到匹配时调用.group()等方法而导致的AttributeError。 - 当你需要提取匹配文本中的特定部分时,请使用分组 和
.group(n)。 - 根据你的需求,在
search、match和findall之间做出正确的选择,如果你不确定用哪个,re.search()通常是更安全、更通用的选择。
