# Python 字符串：split、replace、strip、join、切片与 f-字符串

URL: https://skillaria.top/zh/guides/python/stroki-python

Python 字符串（类型 str）是不可变的 Unicode 字符序列。split() 将字符串切分成列表，join() 把列表重新拼接，replace() 替换子串，strip() 去除两端空白；每个方法都返回新的字符串。插入值最方便的方式是 f-字符串：f"{name}: {price:.2f}"。

字符串几乎出现在每个程序中：用户输入、文件名、CSV 行、API 响应。`str` 类型以 Unicode 存储文本，因此中文、俄语和表情符号无需任何设置即可使用。最常用的方法是 `split`、`replace`、`strip` 和 `join`，输出值则最适合用 f-字符串。下面用示例逐一讲解。

## Python 字符串的结构

字符串可以用单引号或双引号括起来，两者没有区别：`'咖啡'` 和 `"咖啡"` 完全相同。三引号可以创建多行字符串，其中的换行会原样保留。

```
name = "咖啡"
note = """第一行
第二行"""
print(len(name))  # 2 — 字符串的长度（字符数）
```

字符串最重要的特性是不可变性。方法不会修改原字符串，而是返回一个新字符串。因此 `s.replace("a", "b")` 如果不赋值就什么也不会改变——必须写成 `s = s.replace("a", "b")`。这是新手最常犯的错误。

### 转义字符、换行与原始字符串

换行用 `\n` 表示，制表符用 `\t`，反斜杠用 `\\`。前缀 `r` 会创建“原始”字符串：其中的反斜杠不再被处理。这对 Windows 路径和正则表达式很方便。

```
print("合计：\n350 ₽")
path = r"C:\new\table.csv"   # \n 和 \t 不会被当作转义字符
```

较长的表达式可以用括号括起来并换行：括号内相邻的字符串字面量会被 Python 自动拼接。

## split：把字符串拆分成列表

`split()` 按分隔符切分字符串，并返回列表。不带参数时，它按任意空白字符切分，并忽略重复的空格——这对解析命令很方便。

```
"add  咖啡 250".split()        # ['add', '咖啡', '250']
"2026-10-16".split("-")        # ['2026', '10', '16']
"a,b,,c".split(",")            # ['a', 'b', '', 'c']
"key=value=x".split("=", 1)    # ['key', 'value=x']
```

注意区别：指定分隔符时，空片段会被保留。第二个参数 `maxsplit` 限制切分次数，`rsplit()` 则从右侧切分。若要把文本拆成行，使用 `splitlines()`：它同时识别 `\n` 和 `\r\n`，并且不会在末尾留下空元素。

```
text = "咖啡\n打车\n"
text.split("\n")     # ['咖啡', '打车', '']
text.splitlines()    # ['咖啡', '打车']
```

## join：把列表拼接成字符串

`join()` 是相反的操作。它由分隔符字符串调用，参数是字符串列表：

```
items = ["咖啡", "打车", "午饭"]
print(", ".join(items))   # 咖啡, 打车, 午饭
print("\n".join(items))   # 每个条目占一行
```

所有元素都必须是字符串，否则会得到 `TypeError: sequence item 0: expected str instance, int found`。数字要先转换：`", ".join(str(x) for x in amounts)`。

### 字符串拼接与合并

两个字符串可以用 `+` 相加，用 `*` 重复：`"-" * 20`。但在循环中用 `+=` 拼接成百上千个片段很慢，因为每次都会创建新字符串。应该把各部分收集到列表中，然后用一次 `join()` 合并。字符串不能直接与数字相加：`"合计：" + 5` 会引发 `TypeError`，需要使用 `str()` 或 f-字符串。

## replace：替换子串

`replace(old, new)` 替换所有出现的子串。第三个参数限制替换的次数。

```
price = "1 250,50"
price = price.replace(" ", "").replace(",", ".")
print(float(price))                  # 1250.5

"a-b-c".replace("-", "+", 1)         # 'a+b-c'
```

该方法区分大小写，并且只匹配完全相同的文本。若要按模式替换（例如“所有数字”），需要使用 `re` 模块和 `re.sub()` 函数。

## strip、lstrip、rstrip：去除首尾字符

`strip()` 从两端去除空格、制表符和换行符。`lstrip()` 只处理左侧，`rstrip()` 只处理右侧。对用户输入或文件中的字符串，这通常是第一步要做的事。

```
raw = "  咖啡 \n"
raw.strip()       # '咖啡'
raw.rstrip()      # '  咖啡'
"xx咖啡xx".strip("x")   # '咖啡'
```

参数是一组字符，而不是子串：`"abc文本cba".strip("abc")` 会从两端去掉所有的 a、b、c，顺序不限。若要精确去掉前缀或后缀，请使用 `removeprefix()` 和 `removesuffix()`（自 Python 3.9 起可用）。

## 其他常用字符串方法

| 方法 | 作用 | 示例 → 结果 |
| --- | --- | --- |

| `lower()`、`upper()` | 大小写转换 | `"Coffee".lower()` → `'coffee'` |

| `startswith()`、`endswith()` | 检查开头与结尾 | `"a.csv".endswith(".csv")` → `True` |

| `find()` | 子串的位置，未找到返回 -1 | `"咖啡".find("啡")` → `1` |

| `count()` | 出现次数 | `"banana".count("a")` → `3` |

| `isdigit()` | 是否只包含数字？ | `"250".isdigit()` → `True` |

| `zfill()` | 用前导零补足长度 | `"7".zfill(3)` → `'007'` |

检查字符串是否包含某个子串，最简单的方法是运算符 `in`：`if "咖啡" in text.lower():`。字符串用 `==` 逐字符比较，且区分大小写；若要忽略大小写比较，请把两者都转换为 `casefold()` 的结果。

## 字符串切片

字符串是序列，因此可以通过从 0 开始的索引访问字符，负索引从末尾开始计数。切片 `s[start:stop:step]` 返回子串；右边界不包含在内。

```
s = "Python"
s[0]      # 'P'
s[-1]     # 'n'
s[0:3]    # 'Pyt'
s[2:]     # 'thon'
s[::2]    # 'Pto'
s[::-1]   # 'nohtyP' — 反转字符串
```

切片超出边界时不会报错：`s[0:100]` 返回整个字符串。但 `s[100]` 会抛出 `IndexError`。按索引修改字符是不行的（`s[0] = "J"` 会得到 `TypeError`），需要创建新字符串：`"J" + s[1:]`。

## Python 中的 f-字符串

字符串前面加上字母 `f`，花括号中的表达式就会被计算并插入文本中。自 Python 3.6 起，这是格式化字符串的主要方式：比 `format()` 简短，也比旧的 `%` 运算符更快。

```
item = "咖啡"
price = 250
print(f"{item}: {price} ₽")              # 咖啡: 250 ₽
print(f"打折后：{price * 0.9} ₽")         # 打折后：225.0 ₽
print(f"{item=}")                         # item='咖啡' — 调试时很方便
```

### 数字格式化与对齐

在花括号内的冒号之后写格式说明符，它决定舍入、千位分隔符、宽度和对齐方式：

| 写法 | 结果 | 含义 |
| --- | --- | --- |

| `f"{3.14159:.2f}"` | `3.14` | 保留两位小数 |

| `f"{1250000:,}"` | `1,250,000` | 千位分隔符 |

| `f"{1250000:_}"` | `1_250_000` | 用下划线代替逗号 |

| `f"{0.256:.1%}"` | `25.6%` | 百分比 |

| `f"{'咖啡':<10}|"` | `咖啡 |` | 左对齐，宽度 10 |

| `f"{250:>8}"` | ` 250` | 右对齐 |

| `f"{7:03d}"` | `007` | 用零补足 |

对齐功能适合在终端中输出表格：`f"{name:<12}{amount:>10.2f}"` 可以让各列整齐排列。注意，格式化只用于输出。金额应以分为单位保存（`int`）或使用 `Decimal`，而不是 `float`：`0.1 + 0.2` 的结果是 `0.30000000000000004`。

### f-字符串中的引号与换行

从 Python 3.12 起（PEP 701），f-字符串有了正式的语法：花括号内可以使用与外层相同的引号、反斜杠和换行，嵌套深度也不再受限。花括号内的错误现在会精确指出位置。在较旧的版本中，应在花括号内使用另一种引号：`f"{d['key']}"`，换行则通过单独的变量或 `chr(10)` 实现。

多行文本可以使用三引号的 f-字符串：`f"""合计：{total}\n条目数：{count}"""`。

### format() 与 %：旧的写法

在旧代码中可能会遇到 `"{}: {}".format(item, price)` 和 `"%s: %d" % (item, price)`。`format()` 使用的格式说明符与 f-字符串相同。当模板需要与数据分开保存时（例如存放在配置文件中），`format()` 仍然有用。

## 解析字符串：实际示例

把上面的方法结合起来。假设文件中的行形如 `"  2026-10-16; 咖啡 ; 250,50 \n"`，需要得到日期、名称和以分为单位的金额。通常的步骤是：先清理两端，按分隔符切分，再清理每个部分，最后转换类型。

```
line = "  2026-10-16; 咖啡 ; 250,50 \n"

date, item, raw_amount = [p.strip() for p in line.strip().split(";")]
amount_kop = round(float(raw_amount.replace(",", ".")) * 100)

print(date, item, amount_kop)            # 2026-10-16 咖啡 25050
print(f"{item:10.2f}")
```

如果分出来的部分不是三个，解包会报错：`ValueError: not enough values to unpack` 或 `too many values to unpack`。在真实代码中，应该提前检查这类行，或捕获异常。对于带引号和转义字符的真实 CSV 文件，最好使用标准库的 `csv` 模块，而不是 `split`。

### 字符串的常见错误

- **没有保存方法的结果**：不赋值的 `s.strip()` 什么也不改变。
- **对数字列表使用 join** — 会得到 `TypeError`；先用 `map(str, ...)` 转换。
- **对 strip 传入子串**：参数是字符集合，要去掉前缀应使用 `removeprefix()`。
- **区分大小写的比较**：`"Coffee" == "coffee"` 为 `False`。
- **Windows 路径中的反斜杠**：如果没有 `r` 前缀，它们会被当作转义字符。

## t-字符串：模板而不是现成的文本

Python 3.14 引入了 t-字符串。它们看起来像 f-字符串，只是前缀为 `t`，但结果不同：不是现成的字符串，而是 `string.templatelib.Template` 对象。其中，文本片段（`.strings`）和插入的值（`.values`）分别保存。

```
name = ""
tpl = t"你好，{name}！"
print(tpl.strings)   # ('你好，', '！')
print(tpl.values)    # ('',)
```

它的用途在于：库可以在拼接之前获得这些值，并对其进行处理——例如转义 HTML 中的尖括号，或者把参数正确地传入 SQL 查询。f-字符串没有这样的机会，因为它已经完成了拼接。普通输出仍然应该使用 f-字符串。

## 小结

日常处理字符串，Python 只需要一小组工具：`split()` 和 `join()` 负责拆分与组合文本，`strip()` 清理输入，`replace()` 替换片段，切片截取子串，f-字符串则以所需格式输出数值。记住字符串的不可变性：方法返回新字符串，必须保存结果。课程的支出记录器项目中，这些字符串操作和 f-字符串会在实践中反复用到。

## FAQ

**如何获得 Python 字符串的长度？**

函数 len(s) 返回字符数。对于中文和表情符号，计算的是 Unicode 字符，而不是字节；字节数可以用 len(s.encode("utf-8")) 获得。

**如何把数字转换为字符串，再转换回来？**

str(250) 得到 '250'；int("250") 和 float("2.5") 则是反向转换。如果字符串不是合法的数字，int() 会抛出 ValueError，因此应该检查输入。

**为什么 replace 没有改变我的字符串？**

字符串是不可变的，replace 返回的是新字符串。把结果赋值回去：s = s.replace("a", "b")。

**如何检查字符串是否为空？**

空字符串为假，因此直接写 if not s: 即可。如果字符串可能只包含空白，应检查 if not s.strip():。

**t-字符串和 f-字符串有什么区别？**

f-字符串立即返回现成的 str，而 t-字符串（Python 3.14+）是一个 Template 对象，其中文本片段与值分开保存。这样就可以安全地为 HTML 和 SQL 转义数据。


---
Source: Skillaria.Top (https://skillaria.top)
