Pythonの文字列では、ユーザー入力やファイル読み込み時に前後の空白が混入することがよくあります。
こうした不要な空白はstrip
系メソッドで安全に取り除けます。
本記事では、strip
、lstrip
、rstrip
の違いと使い分け、chars
引数の仕様、Unicode空白の落とし穴まで丁寧に解説します。
Pythonで文字列の前後の空白削除の基本
stripの基本と空白の種類
str.strip()
は、文字列の両端にある空白文字(スペースやタブ、改行など)を削除します。
引数なしの場合、PythonはUnicode上で「空白」とみなされる多くの文字を対象にします。
具体的には、半角スペース(U+0020)、タブ(U+0009)、改行(U+000A)、復帰(U+000D)、全角スペース(U+3000)、ノーブレークスペース(U+00A0)などが含まれます。
見えない文字の違いを確かめるには、repr
で可視化すると学習が進みます。
# 両端にさまざまな空白(半角、タブ、改行、全角スペース)を含む例
s = " \tHello, 世界!\n\u3000" # 末尾の \u3000 は全角スペース
print("before:", repr(s))
print("after :", repr(s.strip()))
before: ' \tHello, 世界!\n\u3000'
after : 'Hello, 世界!'
なお、strip()
は「文字列の中間」にある空白は削除しません。
あくまで「前後(両端)」のみです。
lstripで先頭を削除
先頭だけを対象にしたい場合はstr.lstrip()
を使います。
末尾の空白は残ります。
s = " 先頭にだけ空白 "
print("before:", repr(s))
print("lstrip:", repr(s.lstrip())) # 先頭だけの空白が削除される
print("strip :", repr(s.strip())) # 両端の空白が削除される
before: ' 先頭にだけ空白 '
lstrip: '先頭にだけ空白 '
strip : '先頭にだけ空白'
rstripで末尾と改行を削除
末尾だけを対象にしたい場合はstr.rstrip()
です。
引数なしでは、末尾の空白に加えて改行も削除されます。
s = "末尾に空白や改行があります \n"
print("before:", repr(s))
print("rstrip:", repr(s.rstrip())) # 末尾の空白や改行が削除される
before: '末尾に空白や改行があります \n'
rstrip: '末尾に空白や改行があります'
strip/lstrip/rstripの違いと使い分け
先頭・末尾・両端の使い分け
基本的な選び方は、削除したい位置で決めます。
入力値の正規化では多くの場合strip()
が第一選択です。
ログやファイル読み込みで末尾の改行のみを処理したいときはrstrip()
を選びます。
以下に機能を整理します。
メソッド | 削除対象の位置 | 代表的な用途 |
---|---|---|
strip() | 両端 | 入力値の前後整形、CSVセルの正規化 |
lstrip() | 先頭のみ | 左寄せ整形、左側の区切り記号除去 |
rstrip() | 末尾のみ | 行末の空白や改行の処理、末尾スラッシュや句読点の整理 |
挙動の違いはコードで確かめるのが一番です。
s = " \tデータ \n"
print("orig :", repr(s))
print("strip :", repr(s.strip())) # 両端
print("lstrip:", repr(s.lstrip())) # 先頭のみ
print("rstrip:", repr(s.rstrip())) # 末尾のみ
orig : ' \tデータ \n'
strip : 'データ'
lstrip: 'データ \n'
rstrip: ' \tデータ'
末尾改行だけ消す rstrip(“\n”)
末尾の改行だけを消したいケースでは、引数に\n
を渡します。
これによりスペースなど他の空白は維持されます。
Windows系の改行(\r\n
)にも対応するなら\r\n
を指定します。
1行分だけ確実に消すならremovesuffix
(Python 3.9+)も便利です。
line = "値は42です \n" # 末尾にスペースと改行がある
print("rstrip(): ", repr(line.rstrip())) # 末尾の空白も改行も削除
print("rstrip('\\n'): ", repr(line.rstrip("\n"))) # 改行だけ削除、末尾スペースは残る
print("rstrip('\\r\\n'):", repr("abc\r\n".rstrip("\r\n"))) # Windows改行に対応
print("removesuffix: ", repr("abc\n".removesuffix("\n"))) # ちょうど1つの改行だけ削除
rstrip(): '値は42です'
rstrip('\n'): '値は42です '
rstrip('\r\n'): 'abc'
removesuffix: 'abc'
sys.stdin.readline()
で1行読み込んだ文字列は改行を含むため、rstrip("\n")
で取り除くのが定番です。
input()
はすでに末尾改行を含まない点に注意します。
入力やCSVの空白削除
フォームやCLI入力では、数値やIDの前後に空白が混ざることがあります。
strip()
してから変換・比較するのが安全です。
# ユーザー入力を想定した整形
raw = " 12345 " # 例: 入力値(本来は input() の戻り値)
user_id = raw.strip() # 前後の空白だけ削除
print(user_id, user_id.isdigit())
12345 True
CSVでは区切り文字の直後に空白が入る場合があります。
csv
モジュールのskipinitialspace=True
でカンマ後の空白を無視できますが、セルの末尾や引用符内の空白は残ることがあります。
必要に応じて各フィールドにstrip()
を適用します。
import csv
from io import StringIO
data = StringIO("name, score\n Alice , 10 \nBob,20\n' Carol ' , 30\n")
# カンマ後の空白は無視する設定
reader = csv.reader(data, skipinitialspace=True)
rows = []
for row in reader:
# 各セルの前後空白も明示的に削除
clean = [cell.strip() for cell in row]
rows.append(clean)
print(rows)
[['name', 'score'], ['Alice', '10'], ['Bob', '20'], ["' Carol '", '30']]
上の例では、引用符そのものはデータの一部として残っています。
これはcsv
の引用解釈が行われない形(単引用符)だからです。
もし引用符をデータから落としたい場合は、後述のstrip(chars)
などで不要文字を取り除けます。
strip(chars)で削除する文字を指定
chars引数の仕様と注意点
strip
系メソッドに文字列を渡すと、その「文字列に含まれる各文字の集合」を「削除対象の文字集合」として扱います。
つまり「部分文字列」ではなく「文字の集合」です。
順番は関係ありません。
対象集合に含まれる文字が、前後に存在する限り繰り返し取り除かれます。
s = "...Hello???"
print(s.strip("?."))
# 上記は「ピリオド(.)とクエスチョン(?)を前後から取り除く」の意味
Hello
部分文字列は削られない
「この単語ごと消してほしい」という用途には不向きです。
例えばstrip("ab")
は「aとbの集合」を意味し、”ab”という2文字の並びを意味しません。
print("abXYZba".strip("ab")) # a か b が前後からなくなるだけ
print("ZZabcZZ".strip("abc")) # a, b, c の集合として解釈。中央は影響なし
XYZ
ZZabcZZ
開始や終了の「特定の語」を1回だけ除去したい場合は、removeprefix
やremovesuffix
が適しています。
print("prefix_value".removeprefix("prefix_"))
print("name.csv".removesuffix(".csv"))
value
name
空白以外の不要文字の例
前後の記号や括弧、引用符を落としたい時に有用です。
print("***hello***".strip("*")) # アスタリスクを前後から除去
print("「こんにちは」".strip("「」")) # 和文の括弧を除去
print("価格:¥120".lstrip("価格:¥")) # 左側の集合に含まれる文字を除去
print("https://example.com///".rstrip("/")) # 末尾のスラッシュ連続を除去
hello
こんにちは
120
https://example.com
rstrip("/")
は末尾の全てのスラッシュを削る点に注意します。
URLのhttps://
部分の//
は末尾ではないため影響を受けません。
落とし穴とベストプラクティス
中間の空白は削除されない
strip
系は「前後」に限定されます。
中間の空白を削る場合は、用途に応じて別の手段を選びます。
- すべての半角スペースを消したい:
replace(" ", "")
- あらゆる空白(タブや改行を含む)をまとめて除去: 正規表現で
\s
を使う - 連続空白を1つに整形:
' '.join(s.split())
import re
s = " A B\tC \nD "
print("strip():", repr(s.strip())) # 前後のみ
print("replace:", repr(s.replace(" ", ""))) # 半角スペースだけ全削除
print("re.sub :", repr(re.sub(r"\s+", "", s))) # あらゆる空白を全削除
print("normalize spaces:", repr(" ".join(s.split()))) # 単語間1スペースへ整形
strip(): 'A B\tC \nD'
replace: 'AB\tC\nD'
re.sub : 'ABCD'
normalize spaces: 'A B C D'
全角スペースやNBSPへの対処
Python 3のstrip()
は、原則としてUnicodeの空白(例えば全角スペース U+3000、ノーブレークスペース U+00A0)も削除対象です。
ただし、HTML由来の不可視文字やゼロ幅スペース(U+200B)などは「空白」とみなされないため残ることがあります。
次の例では、NBSP(ノーブレークスペース)、全角スペース、ゼロ幅スペースを混ぜています。
import unicodedata as ud
s = "\u00A0全角\u3000とNBSP\u00A0とZWSP\u200B\u00A0" # \u200B はゼロ幅スペース
print("before:", repr(s))
print("strip :", repr(s.strip())) # NBSPや全角スペースは多くの環境で削除される
print([ud.name(ch, "UNKNOWN") for ch in s]) # 各文字の名前を確認
before: '\xa0全角\u3000とNBSP\xa0とZWSP\u200b\xa0'
strip : '全角\u3000とNBSP\xa0とZWSP\u200b' # ゼロ幅スペースは残りうる
['NO-BREAK SPACE', 'CJK UNIFIED IDEOGRAPH-5168', 'IDEOGRAPHIC SPACE', 'HIRAGANA LETTER TO', 'LATIN CAPITAL LETTER N', 'LATIN CAPITAL LETTER B', 'LATIN CAPITAL LETTER S', 'LATIN CAPITAL LETTER P', 'NO-BREAK SPACE', 'HIRAGANA LETTER TO', 'LATIN CAPITAL LETTER Z', 'LATIN CAPITAL LETTER W', 'LATIN CAPITAL LETTER S', 'LATIN CAPITAL LETTER P', 'ZERO WIDTH SPACE', 'NO-BREAK SPACE']
ゼロ幅スペース(U+200B)やBOM(U+FEFF)のような「不可視だが空白扱いではない」文字を確実に除去したい場合は、translate
やreplace
を併用します。
# 不可視の制御・書式文字を消すための翻訳テーブルを作る例
INVISIBLE = "\u200B\u200C\u200D\uFEFF" # ZWSP, ZWNJ, ZWJ, BOM
table = str.maketrans({ord(ch): None for ch in INVISIBLE})
s = "\uFEFF\u200Bタイトル\u200D" # 先頭にBOM、途中にゼロ幅
print("before:", repr(s))
print("clean :", repr(s.translate(table).strip()))
before: '\ufeff\u200bタイトル\u200d'
clean : 'タイトル'
逆に、「ASCIIの空白だけを対象にしたい(全角スペースは削らない)」なら、対象集合を明示します。
ascii_ws = " \t\r\n\f\v" # ASCIIの空白クラス
s = "\u3000全角と半角 \n" # 先頭に全角スペース、末尾に半角+改行
print(repr(s.strip(ascii_ws))) # 全角スペースは残る
'\u3000全角と半角'
Unicodeの空白に注意
何が「空白」かはUnicodeの定義に基づき、str.isspace()
で判定できます。
データクリーニング時に、意図しない文字が混ざっていないかを確認する習慣が役立ちます。
chars = [" ", "\t", "\n", "\r", "\x0b", "\x0c", "\u00A0", "\u3000", "\u200B"]
for ch in chars:
code = f"U+{ord(ch):04X}"
print(code, repr(ch), "isspace?", ch.isspace())
U+0020 ' ' isspace? True
U+0009 '\t' isspace? True
U+000A '\n' isspace? True
U+000D '\r' isspace? True
U+000B '\x0b' isspace? True
U+000C '\x0c' isspace? True
U+00A0 '\xa0' isspace? True
U+3000 '\u3000' isspace? True
U+200B '\u200b' isspace? False
ゼロ幅スペース(U+200B)がisspace()
でFalse
になっていることがわかります。
こうした文字はstrip()
では落ちないため、必要に応じてtranslate
や正規表現で個別対応してください。
まとめ
strip
、lstrip
、rstrip
は、文字列の前後整形における最重要メソッドです。
両端を整えるならstrip()
、先頭だけならlstrip()
、末尾や改行処理ならrstrip()
という基本を押さえ、改行だけを消したいときはrstrip("\n")
やremovesuffix("\n")
を選ぶと安全です。
chars
引数は「部分文字列」ではなく「文字集合」であること、strip()
は中間の空白を削除しないことを理解しておくと、意図しないデータ破壊を避けられます。
さらに、全角スペースやNBSPなどUnicode空白の扱い、ゼロ幅スペースやBOMのような不可視文字への対処法を身につければ、入力値やCSVのクリーニングを堅牢に行えます。
データの性質に合わせて、対象とする空白や不要文字を明示し、strip
系とtranslate
や正規表現を組み合わせるのがベストプラクティスです。