一、引言
在处理文本数据时,经常需要查找某个子串是否存在、在什么位置,或者将某些内容替换为其他内容。Python 字符串提供了丰富的方法来实现这些操作。本文将系统介绍字符串的查找与替换方法,并给出实用案例。
二、字符串查找方法
2.1 find() —— 查找子串第一次出现的位置
find(sub[, start[, end]]) 返回子串 sub 在字符串中第一次出现的索引。如果找不到,返回 -1。
text = "Hello Python, welcome to Python world"
print(text.find("Python")) # 6
print(text.find("Java")) # -1
可以指定查找范围 start 和 end(切片索引,含头不含尾):
print(text.find("Python", 10)) # 从索引10开始查找,返回 25
print(text.find("Python", 10, 20)) # 在10-20之间查找,返回 -1
2.2 rfind() —— 从右侧查找
rfind() 从字符串末尾开始查找,返回最后一次出现的位置。
print(text.rfind("Python")) # 25
2.3 index() 和 rindex() —— 找不到会抛出异常
index() 与 find() 用法相同,但如果找不到子串,会抛出 ValueError。
print(text.index("Python")) # 6
# print(text.index("Java")) # ValueError: substring not found
同样,rindex() 是从右侧查找的版本,找不到也抛出异常。
2.4 count() —— 统计子串出现次数
print(text.count("Python")) # 2
print(text.count("o")) # 4
2.5 in 操作符 —— 判断是否存在
if"Python"in text:
print("找到了")
2.6 startswith() 和 endswith() —— 判断开头或结尾
print(text.startswith("Hello")) # True
print(text.endswith("world")) # False
可以指定范围:
print(text.startswith("Python", 6)) # 从索引6开始是否以"Python"开头,True
三、字符串替换方法
3.1 replace() —— 替换子串
replace(old, new[, count]) 将字符串中的 old 子串替换为 new,并返回新字符串。可以指定最大替换次数 count(默认全部替换)。
s = "I like Python, Python is great"
s2 = s.replace("Python", "Java")
print(s2) # I like Java, Java is great
# 只替换一次
s3 = s.replace("Python", "Java", 1)
print(s3) # I like Java, Python is great
注意:replace() 返回新字符串,原字符串不变。
3.2 translate() —— 字符映射替换
translate(table) 根据转换表 table 对字符串中的字符进行替换。转换表通常由 str.maketrans() 创建。
# 创建转换表:将 'a'->'1', 'b'->'2', 'c'->'3'
table = str.maketrans("abc", "123")
s = "abcde"
s2 = s.translate(table)
print(s2) # 123de
也可以指定要删除的字符(通过第三个参数):
table = str.maketrans("abc", "123", "de") # 删除 'd' 和 'e'
s = "abcde"
s2 = s.translate(table)
print(s2) # 123
translate() 对于单个字符的替换非常高效,适合加密或过滤。
3.3 expandtabs() —— 替换制表符
将字符串中的制表符 \t 替换为空格,默认每个制表符替换为 8 个空格,可指定大小。
s = "a\tb\tc"
print(s.expandtabs(4)) # a b c(每个\t变成4个空格)
3.4 使用切片和拼接实现复杂替换
对于更灵活的替换(如正则表达式式替换),可以结合 find 和切片手动实现。但通常更推荐使用 re 模块(后续介绍)。
四、实战案例
案例1:统计单词出现次数
text = "Python is great. Python is powerful."
word = "Python"
count = text.count(word)
print(f"'{word}' 出现了 {count} 次")
案例2:敏感词过滤(简单版)
deffilter_sensitive(text, sensitive_words):
for word in sensitive_words:
text = text.replace(word, "*" * len(word))
return text
msg = "这个产品真垃圾,质量太差"
sensitive = ["垃圾", "太差"]
print(filter_sensitive(msg, sensitive)) # 这个产品真**,质量**
案例3:替换文件中的占位符
template = "Hello {name}, your score is {score}"
data = {"name": "小明", "score": 95}
result = template
for key, value in data.items():
result = result.replace("{" + key + "}", str(value))
print(result) # Hello 小明, your score is 95
(更专业的做法是用 format 或 format_map,但这里展示替换逻辑)
案例4:字符映射加密(凯撒加密)
defcaesar_encrypt(text, shift):
# 创建转换表
lower = "abcdefghijklmnopqrstuvwxyz"
upper = lower.upper()
shifted_lower = lower[shift:] + lower[:shift]
shifted_upper = upper[shift:] + upper[:shift]
table = str.maketrans(lower + upper, shifted_lower + shifted_upper)
return text.translate(table)
plain = "Hello World"
encrypted = caesar_encrypt(plain, 3)
print(encrypted) # Khoor Zruog
案例5:查找并高亮显示关键词
defhighlight(text, keyword, start_tag="**", end_tag="**"):
idx = text.lower().find(keyword.lower())
while idx != -1:
text = text[:idx] + start_tag + text[idx:idx+len(keyword)] + end_tag + text[idx+len(keyword):]
idx = text.lower().find(keyword.lower(), idx + len(start_tag) + len(keyword) + len(end_tag))
return text
s = "Python is great. I love Python."
print(highlight(s, "python")) # **Python** is great. I love **Python**.
(注意:这里只是演示,实际可能破坏原大小写,可以优化)
五、注意事项
- 1. 字符串不可变:所有查找和替换方法都不会修改原字符串,而是返回新字符串。需要赋值给变量才能保存结果。
- 2. 查找 vs 索引:
find() 返回 -1 表示没找到,而 index() 抛出异常。按需选择。 - 3. 效率:
replace() 是高效的,但在循环中多次使用可能性能下降。对于大量替换,可以考虑先编译正则表达式(后续介绍)。 - 4.
translate() 适合单字符替换:比多次 replace() 快得多。 - 5. 大小写敏感:默认方法是大小写敏感的,如需忽略大小写,可先将字符串转换为统一大小写(如
lower())。 - 6. 边界处理:
find() 的 start 和 end 参数与切片规则一致,start 包含,end 不包含。
六、总结
| | |
find() | | |
rfind() | | |
index() | | |
rindex() | | |
count() | | |
replace() | | |
translate() | | |
startswith() | | |
endswith() | | |
掌握这些方法,能让你在处理文本时得心应手。结合实际案例多加练习,很快就能熟练运用。