pin_drop当前位置:知识文库 ❯ 图文
re.search详解 - Python正则表达式搜索匹配使用指南
一、re.search 概述
re.search() 是Python正则表达式中最常用的搜索方法。它会扫描整个字符串,查找第一个与正则表达式模式匹配的位置,并返回对应的 Match 对象。如果没有找到任何匹配,则返回 None。
与 re.match() 不同,re.search() 不限制匹配位置,可以从字符串的任意位置开始查找,这使得它非常适合用于日志分析、数据提取、文本搜索等场景。
二、语法与参数
代码示例
re.search(pattern, string, flags=0)
三、基本用法
代码示例
import re
# 基本搜索:在字符串任意位置查找
result = re.search(r'World', 'Hello, World!')
print(result) # <re.Match object; span=(7, 12), match='World'>
print(result.group()) # World
print(result.span()) # (7, 12)
# 如果没找到,返回 None
result = re.search(r'Python', 'Hello, World!')
print(result) # None
# 搜索数字
result = re.search(r'\d+', '订单号: ORD-20240607-001')
if result:
print(f'找到的数字: {result.group()}') # 20240607
print(f'位置: {result.span()}') # (7, 15)
# 使用忽略大小写标志
result = re.search(r'python', 'I love PYTHON programming!', re.IGNORECASE)
print(result.group()) # PYTHON
# 使用分组提取
result = re.search(r'(\d{4})-(\d{2})-(\d{2})', '今天是2024-06-07')
if result:
print(f'完整日期: {result.group(0)}') # 2024-06-07
print(f'年份: {result.group(1)}') # 2024
print(f'月份: {result.group(2)}') # 06
print(f'日期: {result.group(3)}') # 07
四、与 re.match 的区别
re.search() 和 re.match() 是Python正则表达式中最容易混淆的两个方法。它们的核心区别在于匹配的起始位置:
代码示例
import re
text = 'Contact: admin@example.com for help'
# re.match 只匹配开头,失败
match_result = re.match(r'\w+@\w+\.\w+', text)
print(f're.match: {match_result}') # None
# re.search 扫描全文,成功
search_result = re.search(r'\w+@\w+\.\w+', text)
print(f're.search: {search_result.group()}') # admin@example.com
# 使用 ^ 让 re.search 等价于 re.match
print(re.search(r'^\w+@\w+\.\w+', text)) # None
五、完整代码示例
代码示例
import re
# ========== 示例1: 从日志中提取错误信息 ==========
def extract_error(log_text):
"""从日志文本中搜索错误信息"""
pattern = r'ERROR[:\s]+(.+?)(?:\n|$)'
match = re.search(pattern, log_text)
if match:
return match.group(1).strip()
return None
log = """
2024-06-07 10:00:00 INFO: Application started
2024-06-07 10:00:05 WARNING: Low memory
2024-06-07 10:00:10 ERROR: Database connection timeout
2024-06-07 10:00:15 INFO: Retrying connection
"""
print(extract_error(log)) # Database connection timeout
# ========== 示例2: 提取网页中的标题 ==========
def extract_title(html):
"""从HTML中提取<title>标签内容"""
pattern = r'<title\s*>(.*?)</title\s*>'
match = re.search(pattern, html, re.IGNORECASE)
return match.group(1) if match else None
html = '<html><head><TITLE>Python教程 - 正则表达式</TITLE></head></html>'
print(extract_title(html)) # Python教程 - 正则表达式
# ========== 示例3: 查找并提取IP地址 ==========
def find_ip(text):
"""在文本中搜索IP地址"""
pattern = r'\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b'
match = re.search(pattern, text)
return match.group() if match else None
text = '服务器IP: 192.168.1.100, 端口: 8080'
print(find_ip(text)) # 192.168.1.100
# ========== 示例4: 提取URL中的查询参数 ==========
def extract_param(url, param_name):
"""从URL中提取指定查询参数的值"""
pattern = rf'[?&]{param_name}=([^&]+)'
match = re.search(pattern, url)
return match.group(1) if match else None
url = 'https://example.com/search?q=python&page=2&sort=relevance'
print(extract_param(url, 'q')) # python
print(extract_param(url, 'page')) # 2
print(extract_param(url, 'sort')) # relevance
# ========== 示例5: 提取Markdown链接 ==========
def extract_markdown_link(text):
"""提取Markdown格式的链接"""
pattern = r'\[([^\]]+)\]\(([^)]+)\)'
match = re.search(pattern, text)
if match:
return {'text': match.group(1), 'url': match.group(2)}
return None
md = '访问 [Python官方文档](https://docs.python.org/3/) 获取更多信息'
result = extract_markdown_link(md)
print(result) # {'text': 'Python官方文档', 'url': 'https://docs.python.org/3/'}
六、注意事项
⚠️ 注意1:
re.search()只返回第一个匹配结果。如果需要找到所有匹配项,请使用re.findall()或re.finditer()。
⚠️ 注意2:匹配结果可能为
None,调用.group()前一定要先判断。推荐使用if match:或三元表达式match.group() if match else None。
⚠️ 注意3:在使用
.匹配任意字符时,默认不匹配换行符。如果需要跨行匹配,请添加re.DOTALL(或re.S)标志,或使用[\s\S]代替.。
七、小结
-
全文搜索:re.search() 扫描整个字符串,返回第一个匹配结果,适合查找和提取数据
-
首次匹配:只返回第一个匹配项,如需所有匹配请使用 re.findall() 或 re.finditer()
-
与match区别:re.match只从开头匹配,re.search可在全局搜索,根据场景选择合适的方法
-
安全检查:使用前务必判断返回值是否为None,避免AttributeError异常
八、练习题
练习1
编写函数 extract_version(text),从文本中搜索并提取版本号(格式如 v1.2.3 或 2.0.1)。
练习2
编写函数 extract_css_property(css, property_name),从CSS代码中提取指定属性的值。例如从 color: #2196F3; 中提取 #2196F3。
常见问题
re.search 和 re.findall 有什么区别?
re.search 只返回第一个匹配结果(Match对象或None),而 re.findall 返回所有匹配结果的列表。如果你只需要第一个匹配用 re.search,需要所有匹配用 re.findall。
re.search 能找到所有匹配吗?
不能。re.search 只返回第一个匹配。要获取所有匹配,可以使用 re.findall() 返回字符串列表,或使用 re.finditer() 返回 Match 对象迭代器(适合需要位置信息的场景)。
如何让 . 匹配换行符?
默认情况下 . 不匹配换行符。添加 re.DOTALL(或 re.S)标志即可:re.search(r'.+', text, re.DOTALL)。或者使用 [\s\S] 来替代 .,它可以匹配包括换行符在内的所有字符。
re.search 和 re.finditer 如何选择?
如果只需要匹配的字符串内容,用 re.findall 更简洁;如果需要每个匹配的位置信息(span)、分组详情等,用 re.finditer 返回的 Match 对象迭代器更合适。
本文涉及AI创作
内容由AI创作,请仔细甄别