移除字串右側(結尾)特定字元是路徑正規化、文字清洗、協議解析的高頻需求。Python rstrip() 方法回傳新字串,移除結尾連續出現的指定字元集合中的字元,預設移除空白字元。本文詳細說明語法、行為細節、與 removesuffix() 差異、實戰應用與進階技巧。
str.rstrip([chars])
chars 是字元集合,非後綴字串。"abc".rstrip("bc") 移除 'c'、'b',非移除 "bc" 子字串。#!/usr/bin/python3
# 範例 1:預設移除空白
s1 = " hello world "
print(repr(s1.rstrip())) # ' hello world'(左側空白保留)
# 範例 2:移除指定字元
s2 = "88888888this is string example....wow!!!8888888"
print(s2.rstrip('8')) # 88888888this is string example....wow!!!
# 範例 3:字元集合行為(非後綴匹配)
s3 = "example"
print(s3.rstrip("ple")) # 'exam'(移除 e、l、p,遇到 a 停止)
s4 = "hello.xyz"
print(s4.rstrip("xyz.")) # 'hello'(移除 z、y、x、.)
# 範例 4:順序無關
print("cba".rstrip("abc")) # ''(全移除)
print("abc".rstrip("cba")) # ''(同樣全移除)
# 範例 5:無匹配與空字串
print("hello".rstrip("xyz")) # 'hello'
print("".rstrip("abc")) # ''
# 範例 6:Unicode 空白
s5 = "測試 \t\n\u3000"
print(repr(s5.rstrip())) # '測試'(含全形空格)
# 目標:移除後綴 ".bak"
filename = "document.txt.bak"
# 錯誤:rstrip 字元集合行為
print(filename.rstrip(".bak")) # 'document.tx'(移除 k、a、b、.、t、x...)
# 正確:Python 3.9+ removesuffix()
print(filename.removesuffix(".bak")) # 'document.txt'
# 相容寫法
if filename.endswith(".bak"):
filename = filename[:-len(".bak")]
paths = ["/home/user/", "/var/log//", "///etc/", "file.txt"]
normalized = [p.rstrip("/") for p in paths]
print(normalized) # ['/home/user', '/var/log', '///etc', 'file.txt']
# 注意:rstrip("/") 會移除所有尾部斜線
# 若需保留根目錄 "/"
def normalize_path(p):
stripped = p.rstrip("/")
return stripped if stripped else "/"
print(normalize_path("/")) # '/'
print(normalize_path("/home/")) # '/home'
lines = ["line 1\n", "line 2\r\n", "line 3\r", "line 4"]
cleaned = [line.rstrip("\n\r") for line in lines]
print(cleaned) # ['line 1', 'line 2', 'line 3', 'line 4']
# 或用通用方法
cleaned = [line.rstrip() for line in lines] # 移除所有尾部空白
raw_fields = [" name ", " age ", " city "]
clean_fields = [f.strip() for f in raw_fields] # 兩側
# 或僅右側
clean_fields = [f.rstrip() for f in raw_fields]
def parse_message(data, delimiter="\r\n"):
"""假設訊息以 delimiter 結尾"""
if data.endswith(delimiter):
return data[:-len(delimiter)]
return data # 或拋出錯誤
# rstrip 版本(若分隔符為單字元集合)
def parse_lines(data):
return [line.rstrip("\r\n") for line in data.split("\n")]
| 方法 | 方向 | 參數型態 | 行為 | Python 版本 |
|---|---|---|---|---|
| rstrip() | 右 | 字元集合 | 移除尾部連續匹配字元 | 所有 |
| lstrip() | 左 | 字元集合 | 移除首部連續匹配字元 | 所有 |
| strip() | 兩側 | 字元集合 | 移除首尾連續匹配字元 | 所有 |
| removesuffix() | 右 | 後綴字串 | 完全匹配後綴才移除 | 3.9+ |
| removeprefix() | 左 | 前綴字串 | 完全匹配前綴才移除 | 3.9+ |
def rstrip_preserve_internal(s, chars=None):
"""僅移除字串末端連續 chars,不影響中間"""
return s.rstrip(chars)
# 測試
print(repr(rstrip_preserve_internal("a b c "))) # 'a b c'
print(repr(rstrip_preserve_internal("a b c ", " "))) # 'a b c'
import re
def rstrip_pattern(s, pattern):
"""移除尾部匹配正則的內容"""
return re.sub(pattern + r'$', '', s)
print(rstrip_pattern("file123.txt", r'\d+')) # 'file.txt'
print(rstrip_pattern("error_404", r'_\d+')) # 'error'
print(rstrip_pattern("test.v1.2.3", r'\.\d+(\.\d+)*$')) # 'test'
def clean_file_lines(input_path, output_path, chars=None):
with open(input_path, 'r', encoding='utf-8') as fin, \
open(output_path, 'w', encoding='utf-8') as fout:
for line in fin:
fout.write(line.rstrip(chars) + '\n')
# 移除所有行尾空白
clean_file_lines('input.txt', 'output.txt')
rstrip() 是移除字串右側字元的標準方法,**參數為字元集合而非後綴字串**是核心概念。若需移除固定後綴,Python 3.9+ 請用 removesuffix(),舊版用 endswith() 切片。搭配 lstrip()、strip() 可處理各種修剪需求。理解「字元集合、連續匹配、遇不匹配停止」三原則,能避免 90% 誤用。檔案讀取、路徑處理、協議解析是典型應用場景。