閉じる

【Python】文字列スライス入門|指定範囲の部分文字列を自在に取得する方法

Pythonの文字列スライスは、特定の範囲の文字だけを手軽に取り出せる、とても強力な機能です。

本文では、基本的な書き方から実用的な使い方、注意点まで、はじめての方でもわかるように順を追って詳しく解説します。

サンプルコードや図解を交えながら、文字列スライスを自在に扱えるレベルを目指していきます。

Pythonの文字列スライスとは

文字列スライスの基本

まず、文字列スライスとは何かを押さえておきます。

Pythonでは、文字列を「配列のように」扱うことができ、インデックスで1文字ずつ参照できます。

このとき、インデックスの範囲を指定して、ある連続した部分をまとめて取り出す仕組みが「スライス」です。

Pythonでは次のように、1文字ごとにインデックスが割り振られます。

先頭が0である点に注意してください。

  • 文字列"Python"のインデックス
    • P → 0
    • y → 1
    • t → 2
    • h → 3
    • o → 4
    • n → 5

このようなインデックスを使って、部分的に文字列を取り出す方法が「スライス」です。

Pythonのスライス表記の書き方

文字列スライスの一般的な書き方は、次のようになります。

文字列[start:stop:step] という3つの値をコロンで区切って指定する形式です。

  • start: 開始位置のインデックス(この位置は含まれる)
  • stop: 終了位置のインデックス(この位置は含まれない)
  • step: 何文字ごとに取り出すか(省略時は1)

実際のコードで確認してみます。

Python
# 基本的なスライスの例
text = "Python"

# インデックス1以上、4未満の部分を取得 (1,2,3文字目)
part = text[1:4]

print(part)  # 期待される出力: "yth"
実行結果
yth

ここで重要なのは、stopで指定した位置の文字は結果に含まれないという点です。

text[1:4]の場合、1,2,3番目の文字が含まれ、4番目の文字は含まれません。

また、次のように各要素を省略することもできます。

  • text[start:] … startから末尾まで
  • text[:stop] … 先頭からstopの直前まで
  • text[::step] … 全体からstepごと
  • text[start:stop] … stepを省略した2項形式

これらの省略記法は、実務で頻繁に使われます。

部分文字列取得でスライスを使うメリット

文字列の一部を取り出す方法は他にもありますが、Pythonではスライスを使うのが基本です。

その理由はいくつかあります。

まず、スライスは読み書きが簡潔で、意図がひと目で伝わるという点が大きなメリットです。

たとえば「先頭3文字を取得したい」という意図はtext[:3]だけで表現できます。

次に、エラーになりにくく、安全に範囲外アクセスを扱える点も実務では重要です。

インデックス指定と違い、多少範囲がずれてもIndexErrorにならずに処理が進みます。

さらに、負のインデックスやstepを組み合わせることで、末尾からの取得や文字飛ばし、反転など、柔軟な操作が1行で書けることも魅力です。

特別なループ処理を書かなくても実現できるため、コードもシンプルになります。

文字列スライスの基本操作

先頭から指定範囲の部分文字列を取得する

もっともよく使うパターンが、「先頭から何文字かを取り出す」ケースです。

この場合は、startを省略し、stopだけを指定します。

Python
text = "Hello, Python!"

# 先頭から5文字を取得
first_five = text[:5]

# 先頭から7文字を取得
first_seven = text[:7]

print(first_five)
print(first_seven)
実行結果
Hello
Hello,

このようにtext[:n]と書くと、0番目からn-1番目までの文字が取得できます。

文字列の先頭が「ヘッダー」のような意味を持つ場合や、固定長の先頭コードを切り出す場合に非常に便利です。

インデックスを使った場合との違い

個々の文字を取り出す場合はtext[0]のように書けますが、これでは1文字しか取り出せません。

複数文字をインデックスだけで扱おうとすると、結局スライスが必要になります。

複数文字を扱うときは、インデックスではなくスライスを使うという意識を持つとよいです。

途中から末尾までの部分文字列を取得する

次に、「途中から最後まで」を取り出すパターンです。

この場合は、startだけを指定し、stopを省略します。

Python
text = "Hello, Python!"

# インデックス7(8文字目)から末尾までを取得
from_seven = text[7:]

# インデックス3から末尾までを取得
from_three = text[3:]

print(from_seven)
print(from_three)
実行結果
Python!
lo, Python!

このように、text[start:]とすると、start位置から最後の文字までをまとめて取得できます。

ログの行末側に重要な情報がある場合など、末尾までまとめて欲しいときに便利です。

長さに依存しない処理が書ける

stopを省略して末尾までを指定することで、文字列の長さを意識せずに処理を書ける点が、実務において大きな利点になります。

たとえば「先頭5文字はヘッダー、それ以降はデータ本体」という文字列を扱う場合、次のように書けます。

Python
record = "HDR01DATA-00123"

header = record[:5]   # 先頭5文字(HDR01)
body   = record[5:]   # 6文字目以降(DATA-00123)

print(header)
print(body)
実行結果
HDR01
DATA-00123

どれだけ長いデータでも、同じ書き方で対応できます。

負のインデックスで後ろから部分文字列を取得する

Pythonの文字列では、負のインデックスを使って末尾から数えることができます。

-1が最後の文字、-2が最後から2文字目、というようにカウントします。

実際のコード例を見てみます。

Python
text = "abcdef"

# 最後の1文字を取得
last_char = text[-1]

# 最後の3文字を取得
last_three = text[-3:]

# 末尾から3文字目まで(つまり先頭〜cまで)
until_third_from_last = text[:-3]

print(last_char)
print(last_three)
print(until_third_from_last)
実行結果
f
def
abc

このように、負のインデックスを使うことで、文字列の長さを事前に調べなくても末尾側の文字を扱えるようになります。

特に、固定長の末尾コード(チェックサムや拡張子など)を扱うときに重宝します。

step(ステップ)で文字を飛ばして取得する

スライスの3つ目の要素であるstepを指定すると、何文字おきに文字を取り出すかを制御できます。

デフォルトは1ですが、2以上を指定すると「飛び飛びの文字列」が得られます。

Python
text = "0123456789"

# 2文字ごとに取得 (0,2,4,6,8)
even_index = text[0:10:2]

# 1文字目から2文字ごとに取得 (1,3,5,7,9)
odd_index = text[1:10:2]

print(even_index)
print(odd_index)
実行結果
02468
13579

stepは省略すれば1になるため、[start:stop][start:stop:1]は同じ意味です。

さらに、stepに負の値を指定すると、逆方向にたどって取得することもできます。

これが文字列の反転にもつながりますが、その詳細は後述します。

実用的な文字列スライスの使い方

ここからは、実務で役立つ具体的な使い方に踏み込んでいきます。

単に「切り出せる」だけでなく、他の処理と組み合わせることで便利なパターンが多数あります。

文字列の一部を抽出して加工する

文字列スライスは、特定の部分だけを取り出して、さらに加工するときに威力を発揮します。

たとえば、日付文字列から年月日を分解して、別の形式に整形する例を考えてみます。

Python
date_str = "2024-12-31"  # "YYYY-MM-DD" 形式の文字列

# 年、月、日をスライスで抽出
year  = date_str[0:4]   # 0〜3文字目
month = date_str[5:7]   # 5〜6文字目
day   = date_str[8:10]  # 8〜9文字目

# "YYYY年MM月DD日" 形式に変換
formatted = f"{year}年{month}月{day}日"

print(formatted)
実行結果
2024年12月31日

このように、固定位置に意味を持つデータが入っている文字列を分解するとき、スライスはシンプルかつ確実です。

スライスとstrメソッドの組み合わせ

抽出したあとにupper()lower()などのメソッドを組み合わせると、簡単な整形処理にも対応できます。

Python
code = "abC123xyz"

# 先頭3文字を取り出して大文字にする
prefix = code[:3].upper()

# 残りをそのまま
rest = code[3:]

result = prefix + rest
print(result)
実行結果
ABC123xyz

このように、「スライスで抽出 → メソッドで加工」という流れは、テキスト処理でよく登場するパターンです。

先頭や末尾の固定長コードを取り出す

実務で頻繁に登場するのが、「先頭や末尾に意味のある固定長コードが付いている文字列」です。

たとえば、商品コードやファイル名などが該当します。

具体例を見てみます。

Python
product = "PRD01-20241231-XYZ"

# 先頭5文字: 商品カテゴリコード
category = product[:5]

# インデックス6〜13: 日付(YYYYMMDD)
date_code = product[6:14]

# 最後の3文字: チェックコード
check_code = product[-3:]

print("category:", category)
print("date_code:", date_code)
print("check_code:", check_code)
実行結果
category: PRD01
date_code: 20241231
check_code: XYZ

このように、位置と長さが決まっている情報はスライスで機械的に切り出すことで、バグの少ないコードを書きやすくなります。

ファイル名から拡張子を取り出す

Pythonではos.path.splitextなどの関数もありますが、単純な拡張子の取得であればスライスでも取り出せます。

Python
filename = "report_2024.csv"

# 最後の4文字が ".csv" だと分かっているケース
ext = filename[-4:]   # ".csv"

# 先頭部分(拡張子なしのファイル名)
name_without_ext = filename[:-4]

print(ext)
print(name_without_ext)
実行結果
.csv
report_2024

末尾側の固定長データを扱うときに、負のインデックスと組み合わせるとコードがすっきりします。

文字列の反転やパターン抽出にスライスを使う

stepに負の値を指定すると、文字列全体を簡単に反転できます。

特に[::-1]という書き方はPythonでよく見かけるイディオムです。

Python
text = "Python"

# 文字列を反転
reversed_text = text[::-1]

print(reversed_text)
実行結果
nohtyP

この[::-1]は次のような意味になります。

  • startを省略 → 末尾から開始
  • stopを省略 → 先頭まで
  • stepが-1 → 逆方向に1文字ずつ進む

特定パターンの抽出にも活用できる

たとえば、偶数番目の文字だけを取り出すなどのパターン抽出も、stepを使って書けます。

Python
text = "A1B2C3D4E5"

# 偶数番目(index 0,2,4,...)の文字だけ取り出す
letters = text[0::2]

# 奇数番目(index 1,3,5,...)の文字だけ取り出す
numbers = text[1::2]

print(letters)  # 期待される: "ABCDE"
print(numbers)  # 期待される: "12345"
実行結果
ABCDE
12345

このように、stepをうまく使うと、ループを書かずに特定のパターンを簡潔に抽出できます。

in演算子との違いと使い分け

部分文字列に関連してよく使われる機能に、in演算子があります。

これは「ある文字列が、別の文字列のどこかに含まれているか」を判定するためのものです。

Python
text = "Hello, Python!"

print("Python" in text)  # True
print("Java" in text)    # False
実行結果
True
False

一方、スライスは「位置と長さを指定して、その部分を取り出す」ためのものです。

Python
text = "Hello, Python!"

# "Python" が文字列中でどの位置か分かっている場合
part = text[7:13]
print(part)
実行結果
Python

両者の使い分けのイメージは次のようになります。

目的適した機能
文字列に特定の語が含まれているかを知りたいin演算子"Python" in text
文字列の特定位置から部分を切り出したいスライスtext[7:13]
含まれている位置も取得したいfind() + スライスidx = text.find("Python")

「存在チェック」にはin、「場所が分かっている部分の取得」にはスライスと覚えておくと、迷いにくくなります。

文字列スライスで気を付けるポイント

便利なスライスですが、Python特有の仕様や落とし穴もあります。

この章では、知っておくと混乱しにくいポイントを解説します。

インデックス範囲外とエラーにならない仕様

通常のインデックス参照では、範囲外を指定するとIndexErrorが発生します。

Python
text = "abc"

# インデックス3は存在しないためエラー
# print(text[3])  # コメントを外すと IndexError

一方、スライスは範囲外になってもエラーにならず、可能な範囲だけを返すという仕様です。

Python
text = "abc"

# stopが大きすぎてもエラーにならない
part1 = text[0:10]   # "abc"

# startが大きすぎると空文字になる
part2 = text[5:10]   # ""

print(f"part1: '{part1}'")
print(f"part2: '{part2}' (長さ: {len(part2)})")
実行結果
part1: 'abc'
part2: '' (長さ: 0)

この性質は、「多少インデックス計算がずれてもコードが落ちない」という意味で安全ですが、逆に「意図せず空文字を返してしまう」原因にもなります。

結果が空文字になっていないかを確認することが大切です。

開始位置・終了位置を省略したときの挙動

すでに何度か登場していますが、スライスではstartやstopを省略できます。

このとき、「省略したときのデフォルト値」が正しくイメージできているかで、読みやすさが変わります。

基本の挙動は次のようになります。

書き方意味実際のイメージ
s[start:]startから末尾までs[start:len(s)]
s[:stop]先頭からstopの手前までs[0:stop]
s[:]先頭から末尾まで(コピー)s[0:len(s)]
s[::step]全体からstepごとs[0:len(s):step]

実際の例で確認してみます。

Python
text = "Python"

# いろいろな省略パターン
a = text[:]      # 全体
b = text[2:]     # インデックス2から末尾まで
c = text[:4]     # 先頭からインデックス3まで
d = text[::2]    # 0,2,4番目の文字
e = text[1::2]   # 1,3,5番目の文字

print(a)
print(b)
print(c)
print(d)
print(e)
実行結果
Python
thon
Pyth
Pto
yhn

特にtext[:]は、元の文字列と同じ内容を持つ別オブジェクトを作りたいときのコピーとしても使われます。

ただし、文字列はそもそもイミュータブル(変更不可)なので、その意味ではコピーの必要がないことも多いです。

マルチバイト文字(日本語)とスライスの注意点

Pythonの文字列は、「文字数」単位でインデックスやスライスを行うため、日本語のようなマルチバイト文字でも基本的には問題なく扱えます。

Python
text = "こんにちは"

print(text[0])   # 先頭の1文字
print(text[:2])  # 先頭から2文字
print(text[-2:]) # 最後の2文字
実行結果
こ
こん
ちは

このように、見た目どおり1文字ずつ数えられます。

ただし、いくつか注意しておきたい点があります。

バイト列と文字列を混同しない

エンコード後のバイト列(bytes型)に対してスライスすると、「バイト単位」で切り出されます。

UTF-8などでは1文字が複数バイトになるため、途中のバイトで切ってしまうと文字化けの原因になります。

Python
text = "こんにちは"

# UTF-8にエンコードしてバイト列にする
b = text.encode("utf-8")

# バイト列を適当にスライス
part = b[:5]

print(b)
print(part)
実行結果
b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'
b'\xe3\x81\x93\xe3\x82\x93'

このpartをそのままデコードしようとすると、途中で切れている場合にはエラーや文字化けが発生し得ます。

「日本語をスライスするなら、基本的には文字列(str)のまま扱う」と覚えておくと安全です。

見た目と文字数が一致しないケース

一部の絵文字や結合文字(濁点付きなど)は、見た目は1文字でも内部的には複数のコードポイントで表現される場合があります。

このようなケースでは、「見た目」と「スライスの単位(コードポイント)」がずれる可能性があります。

一般的な日本語テキスト(日常的な漢字・ひらがな・カタカナだけ)では大きな問題になることは少ないですが、絵文字や特殊文字を多用するシステムでは、見た目ベースでの切り出しには専用ライブラリを検討する必要があります。

まとめ

Pythonの文字列スライスは、インデックス範囲とステップを指定するだけで、先頭・途中・末尾から柔軟に部分文字列を取得できる機能です。

[start:stop:step]という基本形と、start・stopの省略、負のインデックスや負のstepの意味を押さえることで、先頭・末尾の固定長コード抽出や文字列の反転、パターン抽出など、実務的な処理をシンプルに記述できるようになります。

また、スライスは範囲外でもエラーにならない仕様や、日本語を含むマルチバイト文字の扱いにおける注意点もあります。

この記事で紹介した基本と注意点を踏まえて、日々の文字列処理にスライスを積極的に活用してみてください。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!