同事把一段日志处理代码发我,问 s[2:8:2] 为什么取出来是四个字符,他数了半天以为该是六个。python字符串切片看着简单,三个参数一凑齐,边界就容易绕晕。

语法就三个位置

写法是 s[start:stop:step],取的是从 start 开始、到 stop 之前、每 step 个取一个。左闭右开,stop 那个位置永远不包含。省略 start 默认从 0 开始,省略 stop 默认到末尾,省略 step 默认是 1。所以 s[:] 是完整副本,s[1:] 是去掉第一个字符。索引从 0 开始,第 3 个字符的下标是 2,初学最容易在这里差一位。

拿 abcdefg 实际跑一遍

  • s[0:3] 得到 abc,下标 0、1、2。
  • s[-3:] 得到 efg,负号从右边数。
  • s[::2] 得到 aceg,隔一个取一个。
  • s[6:1:-2] 得到 gec,倒着每隔一个取。
  • s[::-1] 得到 gfedcba,整串反转。

负索引从右往左数,-1 是最后一个字符。步长为负时方向反过来,start 要大于 stop,否则得到空串,比如 s[2:5:-1] 就是空的。s[::-1] 是最常用的反转写法,比写循环省事。越界不会报错,s[0:100] 直接把整串给你,超出的部分自动截掉。step 写成 0 会直接报 ValueError: slice step cannot be zero,这个错误一眼就能认出来。

切完还是原字符串,记住这点

字符串不可变,切片返回的是新对象,原变量一个字符都不会变。要改内容只能重新赋值。切片里带变量时,先打印 start、stop、step 的值,再打印 len(s),比盯着代码猜快。处理日志按位置截取字段,用切片比正则轻量,但字段长度变化时容易错位,最好加个长度判断。split 切完再对某一段切片很常见,replace 返回的同样是新字符串,原串不动。

python字符串切片记住左闭右开、负步长反向、越界不报错这三条,剩下就是多打印几次验证。真绕不清的时候,把字符串和下标竖着写出来,一眼就明白。