Python字符串的索引与切片是日常开发中最基础的文本处理技能,无论是解析日志、脱敏隐私数据,还是截取子串、判断回文,都离不开这两个操作。本文从索引基础讲起,逐步深入到步长切片、越界容错、性能特性,最后给出多个生产级实战示例,帮助你在实际项目中高效运用。
一、索引基础:精准定位单个字符
索引用于获取字符串中某一个字符,Python 支持正索引和负索引两种方式。
正索引从左往右从 0 开始计数,字符位置 = 索引值 + 1。例如:- text = 'Python'
- print(text[0]) # P
- print(text[5]) # n
复制代码
负索引从右往左从 -1 开始计数,无需计算长度即可直接取末尾字符。例如:- print(text[-1]) # n
- print(text[-6]) # P
复制代码
利用负索引可以快速获取文件扩展名或判断路径结尾:- filename = 'report_2024.pdf'
- extension = filename[filename.rfind('.'):]
- print(extension) # .pdf
- path = '/home/user/documents/'
- if path[-1] == '/':
- print('路径以/结尾')
复制代码
特别注意:索引越界会直接抛出 IndexError。生产环境中建议使用安全封装:- def safe_get_char(text, index):
- if -len(text) <= index < len(text):
- return text[index]
- return None
复制代码
二、切片基础:批量截取子串
切片语法格式为 text[start:stop:step],其中 start 包含、stop 不包含、step 默认 1。三个参数均可省略,实现各种截取需求。
省略参数的常见写法:- text = 'Python'
- print(text[:3]) # Pyt,从头开始
- print(text[3:]) # hon,截取到末尾
- print(text[:]) # Python,复制整个字符串
- print(text[-3:]) # hon,取最后3个字符
复制代码
步长控制取值间隔,正步长正向取值,负步长反向取值(经典反转写法):- text = 'Python编程'
- print(text[::2]) # Pto编,隔1取1
- print(text[::-1]) # 程编nohtyP,反转字符串
复制代码
利用步长判断回文字符串非常简洁:- def is_palindrome(text):
- clean_text = text.lower().replace(' ', '')
- return clean_text == clean_text[::-1]
复制代码
三、切片高级特性与越界容错
与索引不同,切片越界不会报错,而是自动适配有效范围。这在实际处理时非常安全:- text = 'Python'
- print(text[0:100]) # Python(stop超长自动截断)
- print(text[100:]) # 空字符串(start超出范围)
复制代码
利用切片结合拼接,可以实现字符串的删除、替换、插入:- text = 'Hello, World!'
- # 替换中间内容
- new_text = text[:7] + 'Python' + text[12:]
- print(new_text) # Hello, Python!
- # 插入空格
- text3 = 'HelloWorld'
- new_text3 = text3[:5] + ' ' + text3[5:]
- print(new_text3) # Hello World
复制代码
四、实战业务场景
4.1 文本脱敏
保留后 N 位,其余用 * 代替,适用于手机号、身份证、银行卡等:- def mask_private_text(text, visible=4, mask='*'):
- if len(text) <= visible:
- return text
- return mask * (len(text) - visible) + text[-visible:]
- print(mask_private_text('13812345678', 4)) # *******5678
复制代码
4.2 固定格式日志解析
假设日志格式为“8位日期+6位时间+4位等级+消息”:- log_entry = '20240530143000INFO用户登录成功'
- timestamp = log_entry[:14]
- level = log_entry[14:18]
- message = log_entry[18:]
- print(f'时间:{timestamp},等级:{level},消息:{message}')
复制代码
4.3 字符串轮转(左移/右移)- def rotate_string(text, n):
- if not text:
- return text
- n %= len(text)
- return text[n:] + text[:n]
- print(rotate_string('Python', 1)) # ythonP
复制代码
4.4 文本分页
将长文本按指定长度切分成列表:- def paginate_text(text, page_size):
- return [text[i:i+page_size] for i in range(0, len(text), page_size)]
复制代码
五、性能提示
切片会生成新字符串(返回新内存地址),而非原字符串的引用。因此,对大文本应避免在循环中频繁切片,建议按块一次性处理:- def process_text(text, block_size=100):
- for i in range(0, len(text), block_size):
- block = text[i:i+block_size]
- # 业务处理
复制代码
单字符获取建议用索引 text[0] 而非切片 text[0:1],索引效率更高。
六、新手常见错误
1. 混淆索引与切片:索引取单个字符,越界报错;切片取子串,越界返回空字符串。
2. 步长方向与起止索引不匹配:正向步长必须 start < stop,反向步长必须 start > stop。例如 text[4:0:-1] 正常,text[0:4:-1] 返回空。
建议牢记反转写法 text[::-1],无需关心索引起止。
总结:索引定位单字符,切片截取子串;负索引方便取尾部,步长实现隔位与反转;切片越界不报错,适合安全截取;结合实战场景,灵活用于脱敏、解析、轮转等。掌握这些技巧后,日常 90% 的文本处理需求都可轻松应对。 |