当前位置: 代码网 > it编程>前端脚本>Python > Python中字符串常用方法之查找与替换教学

Python中字符串常用方法之查找与替换教学

2026年09月11日 Python 我要评论
一、开篇:字符串方法的魅力上两篇文章我们学习了字符串的创建和切片。今天开始,我们要进入字符串方法的世界——那些帮你在字符串中查找内容、替换内容、判断内容的强大工具。python

一、开篇:字符串方法的魅力

上两篇文章我们学习了字符串的创建和切片。今天开始,我们要进入字符串方法的世界——那些帮你在字符串中查找内容、替换内容、判断内容的强大工具。

python的字符串有40多个内置方法。别被这个数字吓到——日常开发中真正高频使用的大概15个左右。我将它们分成三组来讲:查找与替换(本文)、分割与拼接、大小写与判断。

查找和替换是你处理文本时最常用的操作——从一段文字中找关键词、替换模板中的占位符、提取特定格式的数据,全都离不开它们。

二、find() 和 rfind():查找子串位置

2.1 find() 基本用法

find() 在字符串中查找子串,返回第一次出现的位置索引。如果找不到,返回 -1(而不是报错)。

text = 'python is easy, python is powerful'

# 查找子串
print(text.find('python'))     # 0(第一次出现的位置)
print(text.find('is'))         # 7
print(text.find('java'))       # -1(没找到)

# 指定查找范围:find(sub, start, end)
print(text.find('python', 10))    # 17(从索引10开始找)
print(text.find('python', 0, 10)) # -1(在0到10范围内没找到)

2.2 rfind():从右边开始查找

text = 'python is easy, python is powerful'

# rfind:找最后一次出现的位置
print(text.rfind('python'))   # 17
print(text.rfind('is'))       # 22(第二个'is')
print(text.find('is'))        # 7(第一个'is')

2.3 find() 实战应用

# 提取文件扩展名
def get_file_extension(filename):
    dot_index = filename.rfind('.')
    if dot_index == -1:
        return ''  # 没有扩展名
    return filename[dot_index:]

print(get_file_extension('report.pdf'))   # .pdf
print(get_file_extension('archive.tar.gz')) # .gz
print(get_file_extension('readme'))       # ''


# 提取url中的协议
def get_url_protocol(url):
    separator = url.find('://')
    if separator == -1:
        return 'unknown'
    return url[:separator]

print(get_url_protocol('https://example.com'))  # https
print(get_url_protocol('ftp://files.server'))   # ftp


# 查找所有出现的位置
def find_all_occurrences(text, substring):
    """查找子串在文本中出现的所有位置"""
    positions = []
    start = 0
    while true:
        pos = text.find(substring, start)
        if pos == -1:
            break
        positions.append(pos)
        start = pos + 1
    return positions

text = 'abababab'
print(find_all_occurrences(text, 'ab'))  # [0, 2, 4, 6]

三、index() 和 rindex():查找但报错

find() 几乎一样,唯一的区别是:找不到时抛出 valueerror 而不是返回 -1

text = 'python编程'

# 找到了——行为完全一样
print(text.index('python'))  # 0
print(text.index('编程'))     # 6

# 区别:找不到时报错
# print(text.index('java'))  # valueerror: substring not found

# 安全的用法——用try-except包裹
def safe_index(text, substring):
    try:
        return text.index(substring)
    except valueerror:
        return -1

print(safe_index('python', 'java'))  # -1

选择 find() 还是 index()

  • 大多数情况用 find():更安全,返回-1即可判断
  • 子串必须存在时用 index():找不到说明数据有问题,报错比静默失败更好

四、count():统计出现次数

text = 'banana'

print(text.count('a'))      # 3
print(text.count('na'))     # 2
print(text.count('z'))      # 0

# 指定范围统计
print(text.count('a', 3))       # 2(从索引3开始统计)
print(text.count('a', 0, 3))    # 1(在0到3范围内统计)

# 实际应用
def count_keywords(text, keywords):
    """统计文本中各个关键词出现的次数"""
    result = {}
    for keyword in keywords:
        result[keyword] = text.lower().count(keyword.lower())
    return result

article = """
python是一种解释型语言。python的设计哲学强调代码的可读性。
python支持多种编程范式,包括面向对象和函数式编程。
"""
word_counts = count_keywords(article, ['python', '编程', '语言'])
print(word_counts)
# {'python': 3, '编程': 2, '语言': 1}

五、startswith() 和 endswith():首尾判断

5.1 基本用法

filename = 'report_2024.pdf'

print(filename.startswith('report'))  # true
print(filename.endswith('.pdf'))      # true
print(filename.endswith('.txt'))      # false

# 可以传入元组来匹配多个选项
print(filename.endswith(('.pdf', '.doc', '.docx')))  # true
print(filename.endswith(('.jpg', '.png', '.gif')))   # false

5.2 指定查找范围

text = 'python programming'

# startswith可以带start和end参数
print(text.startswith('pro', 7))         # true(从索引7开始看)
print(text.startswith('pro', 7, 10))     # true

# endswith也有范围参数(检查指定范围内的结尾)
print(text.endswith('ing', 0, 17))       # true(检查text[0:17]的结尾)

5.3 实战应用

# 过滤文件列表
def filter_files_by_extension(files, extensions):
    """过滤出指定扩展名的文件"""
    return [f for f in files if f.lower().endswith(extensions)]

files = ['data.csv', 'report.pdf', 'photo.jpg', 'script.py', 'notes.txt']
csv_and_py = filter_files_by_extension(files, ('.csv', '.py'))
print(csv_and_py)  # ['data.csv', 'script.py']


# 按前缀分类
def categorize_by_prefix(items, prefix_map):
    """根据前缀对项目分类"""
    categories = {key: [] for key in prefix_map}
    categories['other'] = []

    for item in items:
        categorized = false
        for prefix, category in prefix_map.items():
            if item.startswith(prefix):
                categories[category].append(item)
                categorized = true
                break
        if not categorized:
            categories['other'].append(item)

    return categories

files = ['img_001.jpg', 'doc_report.pdf', 'img_002.png', 'doc_notes.txt']
prefix_map = {'img_': 'images', 'doc_': 'documents'}
print(categorize_by_prefix(files, prefix_map))
# {'images': ['img_001.jpg', 'img_002.png'],
#  'documents': ['doc_report.pdf', 'doc_notes.txt'],
#  'other': []}

六、replace():替换内容

6.1 基本用法

text = 'hello, world! world is beautiful.'

# 基本替换
print(text.replace('world', 'python'))
# hello, python! python is beautiful.

# 限制替换次数
print(text.replace('world', 'python', 1))
# hello, python! world is beautiful.(只替换第一个)

# 删除内容(替换为空字符串)
print(text.replace('world', ''))
# hello, !  is beautiful.
# (注意:多了空格,可能需要额外处理)

# 替换不存在的子串——静默返回原字符串
print(text.replace('java', 'python'))  # 原样返回

6.2 replace() 的高级应用

# 清理文本中的多余空白
def clean_whitespace(text):
    """将连续的空白字符替换为单个空格"""
    import re
    # replace处理简单场景
    text = text.replace('\t', ' ').replace('\n', ' ')
    # 连续的多个空格替换为单个空格
    while '  ' in text:
        text = text.replace('  ', ' ')
    return text.strip()

raw_text = 'hello    world\t\tpython   \n\n   编程'
print(clean_whitespace(raw_text))  # hello world python 编程


# 模板替换
def fill_template(template, **kwargs):
    """用字典的值填充模板中的占位符"""
    result = template
    for key, value in kwargs.items():
        placeholder = '{' + key + '}'
        result = result.replace(placeholder, str(value))
    return result

template = '尊敬的{name},您的订单{order_id}已{status}。'
message = fill_template(
    template,
    name='小明',
    order_id='20240530001',
    status='发货'
)
print(message)  # 尊敬的小明,您的订单20240530001已发货。


# replace的链式调用
text = 'a b c d e'
result = text.replace('a', '1').replace('b', '2').replace('c', '3')
print(result)  # 1 2 3 d e


# 多组替换——使用字典
def multi_replace(text, replacements):
    """一次性执行多组替换"""
    for old, new in replacements.items():
        text = text.replace(old, new)
    return text

replace_map = {
    '&': '&',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
}
html_text = '<div class="content">hello & welcome</div>'
escaped = multi_replace(html_text, replace_map)
print(escaped)

七、translate() 和 maketrans():批量字符映射

对于单字符的批量替换,translate() 比多次调用 replace() 高效得多:

# 创建字符映射表
# str.maketrans(x, y, z)
# x: 要被替换的字符
# y: 替换成的字符(与x逐一对应)
# z: 要删除的字符(可选)

# 凯撒密码——每个字母后移3位
import string
lowercase = string.ascii_lowercase  # 'abcdefghijklmnopqrstuvwxyz'
shifted = lowercase[3:] + lowercase[:3]  # 'defghijklmnopqrstuvwxyzabc'
translation_table = str.maketrans(lowercase + lowercase.upper(),
                                   shifted + shifted.upper())

message = 'hello, python!'
encrypted = message.translate(translation_table)
print(encrypted)  # khoor, sbwkrq!


# 删除所有数字和标点符号
text = '你好,python3!这是一个测试2024。'
# 方法1:删除特定字符
digits_and_punctuation = '0123456789,。!?、:;""''()'
translator = str.maketrans('', '', digits_and_punctuation)
cleaned = text.translate(translator)
print(cleaned)  # 你好python这是一个测试


# 使用translate做简单的文本消毒
def sanitize_filename(filename):
    """清理文件名中的非法字符"""
    illegal_chars = r'<>:"/\|?*'
    translator = str.maketrans(illegal_chars, '_' * len(illegal_chars))
    return filename.translate(translator)

print(sanitize_filename('report:2024/05/30.pdf'))
# report_2024_05_30.pdf

什么时候用 translate() 而不是 replace()

  • 单字符→单字符的批量映射:translate() 快得多
  • 多字符子串→多字符子串:只能用 replace()

八、strip()系列:去除首尾字符

8.1 strip() / lstrip() / rstrip()

# strip():去除首尾的空白字符(默认)
text = '   hello, world!   \n'
print(repr(text.strip()))  # 'hello, world!'

# 去除指定的字符(不是子串,是字符集合!)
text = '###hello, world!###'
print(text.strip('#'))     # 'hello, world!'

text = 'www.example.com'
print(text.strip('w.moc'))  # 'example'
# 注意:strip('w.moc')是一直去除首尾出现的w、.、m、o、c这些字符
# 直到首尾不再出现这些字符为止

# lstrip():只去除左侧
text = '   hello   '
print(repr(text.lstrip()))  # 'hello   '

# rstrip():只去除右侧
text = '   hello   '
print(repr(text.rstrip()))  # '   hello'

8.2 strip() 实战案例

# 清理用户输入
def clean_user_input(text):
    """清理用户输入的首尾空白和特殊符号"""
    return text.strip().strip('.,;:!?。,;:!?')


inputs = ['   小明   ', '小红。。。', '  小刚,,,   ', ',小丽。']
for inp in inputs:
    print(repr(clean_user_input(inp)))
# '小明'
# '小红'
# '小刚'
# '小丽'


# 读取配置文件中的值,去除注释和空白
def parse_config_line(line):
    """解析配置文件的一行"""
    # 去除注释(#后面的内容)
    comment_index = line.find('#')
    if comment_index != -1:
        line = line[:comment_index]

    # 去除首尾空白
    return line.strip()


config_lines = [
    'server = localhost  # 数据库服务器地址',
    'port = 3306         # 数据库端口',
    'username = admin',
    ''
]
for line in config_lines:
    result = parse_config_line(line)
    if result:
        print(f'解析:{result}')

九、replace() vs re.sub():何时用正则

replace() 只能替换确定的字符串。如果需要模式匹配(如"所有数字"、“邮箱地址”),就需要正则表达式:

import re

text = '我的电话是138-1234-5678,他的电话是139-8765-4321。'

# replace做不到——每次号码都不一样
# 用正则表达式
masked = re.sub(r'\d{3}-\d{4}-\d{4}', '***-****-****', text)
print(masked)  # 我的电话是***-****-****,他的电话是***-****-****。


# replace能做到——不需要正则
text = 'hello, world! hello, world!'
print(text.replace('hello', 'hi'))  # hi, world! hi, world!

# replace做不到——大小写不敏感的替换
print(re.sub('hello', 'hi', text, flags=re.ignorecase))  # hi, world! hi, world!

原则:能用 replace() 解决的就用 replace(),简单清晰;需要模式匹配时才用正则。

十、查找与替换的性能对比

import time

text = 'a' * 10000 + 'target' + 'a' * 10000

# find 比 in 更灵活(可以指定位置)
start = time.perf_counter()
pos = text.find('target')
elapsed = time.perf_counter() - start
print(f'find: {elapsed:.8f}秒, 位置={pos}')

# count 和 find 性能差不多
start = time.perf_counter()
cnt = text.count('a')
elapsed = time.perf_counter() - start
print(f'count: {elapsed:.8f}秒, 数量={cnt}')

# replace vs translate(字符替换场景)
chars_to_replace = 'abcdefghijklmnopqrstuvwxyz'
chars_replacement = 'abcdefghijklmnopqrstuvwxyz'

# replace方式
start = time.perf_counter()
result1 = text
for old, new in zip(chars_to_replace, chars_replacement):
    result1 = result1.replace(old, new)
elapsed_replace = time.perf_counter() - start
print(f'replace: {elapsed_replace:.4f}秒')

# translate方式
start = time.perf_counter()
table = str.maketrans(chars_to_replace, chars_replacement)
result2 = text.translate(table)
elapsed_translate = time.perf_counter() - start
print(f'translate: {elapsed_translate:.4f}秒')
# translate快很多倍!

十一、本篇小结

字符串查找与替换方法速查:

方法 功能找不到时
find()查找子串位置返回-1
rfind()从右查找返回-1
index()查找子串位置报valueerror
rindex()从右查找报valueerror
count()统计出现次数返回0
startswith()判断开头返回false
endswith()判断结尾返回false
replace()替换子串返回原字符串
translate()批量字符映射n/a
strip()去除首尾字符可能返回空串

这些方法构成了python字符串处理的基础。日常开发中,find() + replace() + strip() + startswith()/endswith() 这几个占了我90%的字符串查找替换操作。下一篇我们学习分割与拼接——处理csv、日志、路径等结构化文本的核心技能。

以上就是python中字符串常用方法之查找与替换教学的详细内容,更多关于python字符串查找与替换的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com