message ="The red house is between the blue house and the old house"print(message.replace("house","car"))# The red car is between the blue car and the old carprint(message.replace("house","car",2))# The red car is between the blue car and the old house技术支持
headline ="Where's Waldo?"print(headline.find("Waldo",0,6))# -1 (searching "Where'")print(headline.find("Waldo",0,13))# 8 (searching up to the 'o' in Waldo)技术支持
blurbs =["Critics say the lead actor delivers a career-best performance.","Fans argue the actor actor scene was intentionally repetitive.","A clever cameo steals the show."]for blurb in blurbs:# Check whether "actor" appears between indexes 20 and 40 (end exclusive).
window_has_actor ="actor".casefold()in blurb[20:40].casefold()ifnot window_has_actor:print("Window check: actor not found")continue# If "actor actor" appears, collapse to a single "actor".if"actor actor"in blurb:print(blurb.replace("actor actor","actor"))# If "actor actor actor" appears, collapse to a single "actor".elif"actor actor actor"in blurb:print(blurb.replace("actor actor actor","actor"))else:print(blurb)技术支持
输出:
Window check: actor not found
Fans argue the actor scene was intentionally repetitive.
Window check: actor not found技术支持
我们常会想到用
.find()或.index()来检查某段文本是否存在于字符串中——却又会遇到诸如抛出ValueError或漏掉字符串开头匹配等奇怪现象。大小写敏感、切片边界的 off-by-one,以及str上没有.contains()方法,这些都加剧了困惑。解决办法很直接:用对工具。存在性检查用in运算符,位置用.find()/.index(),计数用.count(),替换用.replace()——当需忽略大小写时,再配合一些对 Unicode 友好的技巧。Python 如何处理子字符串搜索
Python 的文本字符串是 Unicode。子字符串操作默认区分大小写,并由 C 实现以提升速度。判断某段文本是否出现在字符串中的最直接方式是使用
in运算符,它通过字符串的__contains__()实现返回布尔值。需要位置或计数时,使用专用的str方法。可选的start和end参数遵循切片语义:start 包含;end 排除。使用 in 判断包含关系
当您只关心子字符串是否存在时,使用
"needle" in haystack。它可读性强且避免了索引处理。若需不区分大小写的检查,请对双方进行归一化。与
.lower()相比,.casefold()对 Unicode 更敏感,是我进行无大小写匹配时的默认选择。"" in s始终为True(空字符串存在于每个字符串中)。str.find() 方法
语法
str.find()返回子字符串的最小索引,若未找到则返回-1。可选的start与end可限制搜索范围。示例与用法
当您需要位置并且可以在未找到时处理返回值而非异常时,请使用
.find()。不要写
if s.find(sub):来检查存在性。如果匹配位于索引 0,该条件为假。str.index() 方法
语法
.index()与.find()类似,但当子字符串缺失时会抛出ValueError。示例与选择时机
当子字符串必须存在,且抛出异常是合适的失败方式时,使用
.index()。str.count() 方法
语法
.count()返回不重叠出现的次数。它也接受start与end边界。示例与边界情况
在无需正则的前提下,使用
.count()快速统计。特殊情况:空字符串。
str.replace() 方法
.replace()返回一个新字符串,其中所有old的出现都被new替换。使用count限制替换次数。替换子字符串
该方法不是就地操作;它会返回副本。
不区分大小写的替换
若需在替换时不区分大小写并保留原有大小写模式,可使用带
re.IGNORECASE的re.sub();如果不需要保留原大小写,可用.casefold()进行归一化。使用 .casefold() 进行不区分大小写的匹配
.casefold()提供更强的、对 Unicode 友好的大小写归一化,在无大小写匹配时优于.lower()。用于前缀与后缀的相关工具
若已知开头/结尾,请使用专用方法——它们比切片或正则更快、更清晰:
s.startswith(prefix)与s.endswith(suffix)(接受元组以指定多个选项)s.removeprefix(prefix)与s.removesuffix(suffix)(Python 3.9+)处理 Pandas 列
当在 DataFrame 的一列中搜索大量字符串时,使用向量化字符串方法。将
regex=False设置为匹配字面文本。注意:
regex=True,因此像.这样的特殊字符会匹配任意字符,除非您禁用正则。na=...处理空值。使用StringDtype时,缺失值在掩码中默认为False。常见陷阱与边界情况
str 上没有 .contains():请用
"sub" in s。"abc".contains("a")会抛出AttributeError。.find() 的真值问题:索引
0为假;请与!= -1比较,或优先用in做存在性检查。.index() 会抛异常:若子字符串可能不存在,请处理
ValueError。空子字符串:
"" in s为True;s.find("")返回0;s.count("")为len(s)+1。大小写敏感:除非您进行归一化或使用正则标志,否则所有操作均区分大小写。
字节与文本:不要在搜索中混用
bytes与str;请解码或编码以匹配类型。子字符串语义:
"ab" in "cat,bat"为False,尽管"a"与"b"分别出现——匹配必须是连续的。可运行的动手示例
这些简短代码片段展示了正确范式,并强调了常见陷阱。
存在性检查
带边界的搜索(start 与 end)
end 是排他的,因此搜索位置与切片语义一致。
计数与替换
Python 字符串查找与替换练习示例
此示例处理一组电影短评。它演示了存在性检查、带边界的搜索,以及无需正则的安全替换。
输出:
结语
简单包含关系用
in运算符;需要位置时用.find()或.index();不重叠计数用.count();替换用.replace()。不区分大小写时用.casefold()归一化;在合适场景优先使用专用的前缀/后缀辅助方法。我们避免将.find()的结果直接转为布尔值,并将空子字符串的行为视为特殊情况,以确保字符串代码既正确又清晰。