杰瑞科技汇

python findall与find

  • str.find(): 是 Python 字符串 的一个内置方法,用于在一个字符串中查找子字符串的位置,它返回的是整数(索引值)。
  • re.findall(): 是 Python 正则表达式 模块 (re) 中的一个函数,用于在字符串中查找所有匹配正则表达式模式的子串,它返回的是一个列表

下面我们分别详细讲解。

python findall与find-图1
(图片来源网络,侵删)

str.find() - 字符串查找

find() 是字符串对象的一个方法,用于查找一个子字符串在另一个字符串中首次出现的位置。

语法

string.find(substring, start, end)

参数

  • substring: 要查找的子字符串。
  • start (可选): 开始查找的位置索引(包含),默认为 0。
  • end (可选): 结束查找的位置索引(不包含),默认为字符串的末尾。

返回值

  • 如果找到子字符串,返回其首次出现的起始索引(一个整数)。
  • 如果没有找到子字符串,返回 -1

示例

text = "Hello, welcome to the world of Python. Python is great."
# 1. 查找存在的子字符串
# 查找 "Python" 首次出现的位置
index = text.find("Python")
print(f"找到 'Python' 的索引是: {index}")
# 输出: 找到 'Python' 的索引是: 24
# 2. 查找不存在的子字符串
# 查找 "Java" 的位置
index_not_found = text.find("Java")
print(f"找不到 'Java',返回: {index_not_found}")
# 输出: 找不到 'Java',返回: -1
# 3. 使用 start 和 end 参数
# 只在索引 30 之后查找 "Python"
index_limited = text.find("Python", 30)
print(f"从索引30之后查找 'Python',索引是: {index_limited}")
# 输出: 从索引30之后查找 'Python',索引是: 38
# 4. 查找空字符串 ""
# 空字符串被认为是存在于任何字符串的开头
index_empty = text.find("")
print(f"空字符串的索引是: {index_empty}")
# 输出: 空字符串的索引是: 0

主要特点

  • 功能: 简单的子字符串匹配。
  • 返回值: 整数(索引)或 -1。
  • 用途: 当你只需要知道某个子串是否存在以及它的位置时使用。
  • 大小写敏感: "Python".find("python") 会返回 -1。

re.findall() - 正则表达式查找

findall()re 模块的核心函数之一,功能强大得多,它使用正则表达式来查找模式。

语法

import re
re.findall(pattern, string, flags=0)

参数

  • pattern: 一个正则表达式模式字符串。
  • string: 要在其中搜索的原始字符串。
  • flags (可选): 控制正则表达式匹配行为的标志,如 re.IGNORECASE (忽略大小写)。

返回值

  • 返回一个列表,列表中包含所有与模式匹配的子字符串
  • 如果模式中没有捕获组,列表中的每个元素都是一个完整的匹配字符串。
  • 如果模式中有捕获组,列表中的每个元素就是对应捕获组的内容(如果只有一个捕获组)或一个包含多个捕获组内容的元组(如果有多个捕获组)。(这是一个非常重要的细节!)

示例

import re
text = "The prices are $10, $20, and $30. The phone numbers are 123-456-7890 and 987-654-3210."
# 1. 查找所有匹配的数字
# \d+ 匹配一个或多个数字
numbers = re.findall(r'\d+', text)
print(f"找到所有数字: {numbers}")
# 输出: 找到所有数字: ['10', '20', '30', '123', '456', '7890', '987', '654', '3210']
# 2. 查找所有价格 (带 $ 符号的)
# \$ 匹配字面量 '$',因为 '$' 在正则中有特殊含义
prices = re.findall(r'\$\d+', text)
print(f"找到所有价格: {prices}")
# 输出: 找到所有价格: ['$10', '$20', '$30']
# 3. 查找所有电话号码
# \d{3}-\d{3}-\d{4} 匹配 3位-3位-4位 的数字
phone_numbers = re.findall(r'\d{3}-\d{3}-\d{4}', text)
print(f"找到所有电话号码: {phone_numbers}")
# 输出: 找到所有电话号码: ['123-456-7890', '987-654-3210']
# 4. 使用捕获组
# 假设我们只想提取电话号码中的区号 (前3位)
# () 定义了一个捕获组
area_codes = re.findall(r'(\d{3})-\d{3}-\d{4}', text)
print(f"找到所有区号: {area_codes}")
# 输出: 找到所有区号: ['123', '987']
# 5. 多个捕获组
# 如果我们想分别提取区号、交换码和号码
phone_parts = re.findall(r'(\d{3})-(\d{3})-(\d{4})', text)
print(f"找到电话号码的各个部分: {phone_parts}")
# 输出: 找到电话号码的各个部分: [('123', '456', '7890'), ('987', '654', '3210')]
# 注意:返回的是一个元组列表,每个元组对应一次匹配的所有捕获组
# 6. 使用 flags (忽略大小写)
text_case = "Hello, WORLD, and world."
words = re.findall(r'world', text_case, re.IGNORECASE)
print(f"忽略大小写查找 'world': {words}")
# 输出: 忽略大小写查找 'world': ['WORLD', 'world']

主要特点

  • 功能: 强大的模式匹配,可以查找复杂的文本结构(如邮箱、URL、特定格式的数字等)。
  • 返回值: 列表。
  • 用途: 当你需要从文本中提取符合特定规则的所有内容时使用。
  • 大小写敏感: 默认区分大小写,但可以通过 re.IGNORECASE 标志来忽略。

总结与对比

特性 str.find() re.findall()
所属模块 Python 内置,字符串方法 re (正则表达式) 模块
查找对象 固定的子字符串 正则表达式模式
功能 简单、直接的子串查找 复杂、灵活的模式匹配
返回值 整数 (首次出现的索引) 或 -1 列表 (所有匹配的子串)
查找方式 从左到右,只找第一个匹配 从左到右,找到所有匹配
捕获组 不适用 非常重要:有捕获组时,返回捕获组的内容
典型用途 "error".find("err") -> 0 re.findall(r'\b\d{3}-\d{2}-\d{4}\b', text) -> ['123-45-6789']

如何选择?

  • 如果你只是想检查一个固定的字符串("error", "warning")是否存在,或者想知道它第一次出现的位置

    • 使用 str.find(),它更简单、直接,性能也稍好。
  • 如果你需要查找的文本有特定的格式或规则(比如所有邮箱、所有手机号、所有金额、所有由3个大写字母组成的单词等)

    python findall与find-图2
    (图片来源网络,侵删)
    • 使用 re.findall(),这是它的专长,能让你用非常简洁的语法完成复杂的查找任务。

简单记忆:find 找的是字符串re.findall 找的是模式

python findall与find-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇