HOWTO · Python
如何在 Python 字符串中查找字符
了解如何查找 Python 字符串中字符或子字符串的零基索引,以及如何处理未找到的情况。
本页内容
Python 字符串的索引从 0 开始。要查找字符或子字符串,可用 find() 查找首次匹配,用 rfind() 查找最后一次匹配,或在未找到时需要引发 ValueError 的情况下用 index()。如果没有匹配项,find() 和 rfind() 都会返回 -1。要收集所有匹配项的索引,可以使用 enumerate() 遍历字符串。下面的代码示例已在提供的 Python 运行环境中执行,各节会说明实际观察到的结果。
这些方法用于搜索字符串,并且区分大小写。每个方法都接受要查找的值,以及可选的 start 和 end 边界:包含 start,但不包含 end。例如,s.find("n", 6, 13) 只搜索从索引 6 到索引 12 的切片。返回值仍是相对于原字符串开头的索引,而不是相对于所搜索切片的位置。
使用 find() 方法查找首次匹配并处理未匹配的情况
在字符串上调用 find(),并传入要查找的字符或子字符串。它会从左向右查找,并返回首次匹配项的索引。如果没有匹配项,它会返回 -1;因此,在把结果用作索引前,应先检查它是否为 -1。
对于 s = "python is fun" 和 c = "n",s.find(c) 返回 5:第一个 n 位于从 0 开始计数的索引 5。该方法的一般形式是 string.find(substring, start, end);省略可选边界时,会搜索整个字符串。
下面是查找首次匹配项的完整示例:
s = "python is fun"
c = "n"
print(s.find(c))
此示例从 s 的开头开始搜索,打印结果为 5。如果查找可能没有匹配项,可以先执行 position = s.find(c),再用 if position != -1: 这样的条件判断,让代码明确处理未找到的情况。
使用 rfind() 方法查找最后一次匹配
需要查找字符或子字符串最后一次出现的位置时,可以使用 rfind()。它从右侧开始搜索并返回最大的匹配索引,但索引仍然从左侧开始计数。与 find() 一样,它接受可选的 start 和 end 边界;如果没有匹配项,则返回 -1。
对于相同的字符串和字符,s.rfind(c) 返回 12,也就是 "python is fun" 中最后一个 n 的索引。该方法的一般形式是 string.rfind(substring, start, end)。
s = "python is fun"
c = "n"
print(s.rfind(c))
此处的结果是 12。最早一次匹配很重要时选择 find(),最后一次匹配很重要时选择 rfind();搜索值不存在本身不会使这两个方法引发错误。
使用 index() 方法在未匹配时引发错误
index() 也会返回首次匹配项的索引,并接受相同的可选 start 和 end 边界。它与 find() 的主要区别在于未匹配时的行为:如果字符串中没有该字符或子字符串,index() 会引发 ValueError,而不是返回 -1。如果未找到应视为错误,请使用它;如果想通过返回值判断是否找到,则使用 find()。
对于 s = "python is fun" 和 c = "n",s.index(c) 返回 5。该方法的一般形式是 string.index(substring, start, end)。
s = "python is fun"
c = "n"
print(s.index(c))
此示例查找第一个 n,因此结果为 5。不要说未匹配时 index() 会返回 ValueError:该方法会引发此异常;如有需要,调用方可以用 try/except 语句处理。
使用 for 循环和 enumerate() 查找所有匹配索引
find()、rfind() 和 index() 每次都只返回一个匹配索引。要查找所有出现位置,可以使用 enumerate() 遍历字符串;它会将每个字符与其从 0 开始计数的索引配对。字符与要查找的值匹配时,将该索引追加到结果中。
s = "python is fun"
c = "n"
lst = []
for pos, char in enumerate(s):
if char == c:
lst.append(pos)
print(lst)
对于这个字符串,匹配索引为 [5, 12]:两个 n 分别位于索引 5 和 12。也可以用列表推导式 [pos for pos, char in enumerate(s) if char == c] 得到相同结果。当不需要单独的循环体时,这种写法能将遍历和匹配条件放在一起。
这两种写法都会按顺序检查字符,并使用相同的从 0 开始计数的索引。每次匹配后还要执行其他操作时,选择循环;如果任务只是收集匹配索引,则选择列表推导式。