TL;DR
このページでは Python で使われる文字列の基本操作方法を網羅的に述べる。
文字列のポイント
- 文字列はイミュータブル(書き換え不可)である
- 文字リテラルは、横に並べるだけでも連結可能
- print() 関数の引数の間には空白が入り、末尾には改行が反映される
※ カタカナ用語の解説は後述する。
str 型
a = 'A'
type(a)
# str
str 型は文字列を扱う型である。シングルクオートか、ダブルクオートで文字列を囲むと str 型の値を定義できる。このことを文字リテラルという。(※ 2)
※ 2:リテラルとは、プログラムに直接記述された値のことを指す。
str()関数を使えば、データ型を文字列に変換できる。
str(1234)
# '1234'
str(1.0e4)
# '10000.0'
str(True)
# 'True'
イミュータブルのコピー
Python の文字列はイミュータブル(書き換え不可)なシーケンス(※1)である。
※1:イミュータブルなシーケンスには、tuple, str, range, bytes などがある。
オブジェクト(データ、機能。変数に代入できるもの)に入っているデータの値、文字列をその場で書き換えることはできない。
しかし、文字列の一部を別の文字列にコピーし、同じ結果を得ることは可能である。
既存の変数を新しい変数に代入すると同じオブジェクトを指すようになる。次のコードをみよう。
x = 'A'
y = x
y # 'A'
x = 'B'
y # 'A' のままである
x に 'A' を代入し、y に x を代入すると同じ値を示す。その後 x の値を変更すると x は 新しく作られた 'B' というオブジェクト を指すようになる。つまり 'A' を格納しているオブジェクトを書き換えているわけではない。y の値は x の値に左右されない。
for 文での挙動
文字列はイテラブル(繰り返し可能)なオブジェクトなので、for 文で文字列を使えば、1 文字ずつ str 型の要素が渡されることが分かる。
for i in 'hello':
print(i)
# h
# e
# l
# l
# o
文字列の改行
文字列の改行は \n
を使う。
print('abcd\nefg')
# abcd
# efg
シングルクォートで囲んだ文字列の中に、\t
を挿入するとタブ文字入れることができる。
print('abcd\tefg')
# abcd efg
エスケープ文字
シングルクォートで囲んだ文字列の中にシングルクオートがある場合、エラーになる。エスケープするには、バックスラッシュ\
を使う。
print('Let's go!')
# SyntaxError: invalid syntax
print('Let\'s go!')
# Let's go!
トリプルクオート
文字列を クォーテーションを使って 3 つ連続で書き囲むと改行を反映させることができる。先頭や末尾にスペースがある場合、それも反映される。
a = """
abc
def
ghi
"""
print(a)
# abc
# def
# ghi
文字の連結
文字の連結は +演算子
を使うと、リテラル文字、文字列変数を連結できる。
文字リテラルの場合、横に並べるだけでも連結可能だが、文字列変数は横に並べて連結することはできない。
'hello' + ' world'
# 'hello world'
'hello' ' world'
# 'hello world'
a = 'hello'
b = 'world'
a b
# SyntaxError: invalid syntax
# マイナスはサポートされてない
'hello world' - 'hello'
# TypeError: unsupported operand type(s) for -: 'str' and 'str'
空白の処理
文字列の連結では、自動的にスペースは追加されない。print() 関数の引数の間には空白が入り、末尾には改行が反映される。
a = 'A'
b = 'B'
c = 'C'
d = 'D'
a + b + c + d
# 'ABCD'
print(a, b, c, d)
# A B C D
演算
文字は演算可能である。*演算子
を使うと文字列を繰り返すことができる。*
は +
より優先度が高い。
name = 'hoge '
name * 3
# 'hoge hoge hoge '
'Hey ' * 3 + 'ビビってる! ' * 2
# 'Hey Hey Hey ビビってる! ビビってる!'
比較演算子
比較演算子を使って比較するとブール値(False および True)が返る。
'abc' == 'abc'
# True
'abc' != 'def'
# True
オフセット
文字列の中にある文字を一つだけ取り出したいときは、文字列変数名の後ろに []
で囲んだ文字であるオフセット(※ 3)を使う。
このインデックス参照は、シーケンス型であるリストやタプルでも機能する。
※ 3:オフセットとは、指定した位置からの距離を示すデータの位置
word = 'abcdefghijklmn'
word[0] # 'a'
word[1] # 'b'
word[-1] # 'n'
文字列はイミュータブル(書き換え不可) なので、書き換えようとするとエラーがでる。
word = 'hello'
word[1] = 'H'
# TypeError: 'str' object does not support item assignment
書き換えたい場合は、以下に示す replace() を使うとよい。
replace()
replace() で文字列を置換できる。
n = 'hello'
n.replace('h', 'k')
# 'kello'
第三引数に数字を設定すると、置換する回数を指定できる。
w = 'abcde abcde abcde abcde abcde'
w.replace('a', 'A', 2)
# Abcde Abcde abcde abcde abcde
スライス
スライスを使えば文字列から部分文字列を抽出することができる。
[:]
はシーケンス全体をスライス[3:]
オフセット 3 から末尾までをスライス[1:4]
2 つ目から 5 つ目までをスライス[-1:]
最後の 文字列をスライス[::2]
2 字ごとにスライス[5::2]
オフセット 5 から末尾まで 2 文字ごとにスライス[:5:2]
先頭からオフセット 5 まで 2 文字ごとにスライス[-1::-1]
末尾から先頭まで逆順に表示[::-1]
末尾から先頭まで逆順に表示
w = '0123456789'
w[:] # 文字列全体が指定される
# '0123456789'
w = '0123456789'
w[3:] # オフセット3から末尾までを切り取る
# '3456789'
w = '0123456789'
w[1:4] # 2つ目から5つ目までをスライスする
# '123'
w = '0123456789'
w[0:4] # 1つ目から4つ目までをスライスする
# '0123'
w = '0123456789'
w[3:9:2] # 3 ~ 9 まで2文字おきに
# '357'
w = '0123456789'
w[-1:] # 最後の 文字列をスライス
# '9'
w = '0123456789'
w[::2] # 2 字ごとにスライス
# 02468
w = '0123456789'
w[5::2] # オフセット 5 から末尾まで 2 文字ごとにスライス
# '579'
w = '0123456789'
w[:5:2] # 先頭からオフセット 5 まで 2 文字ごとにスライス
# 024
w = '0123456789'
w[-1::-1] # 逆順
# '9876543210'
w = '0123456789'
w[::-1] # 逆順
# '9876543210'
format()
format() は文字列の中にある {}
が、format()の引数に渡した値に置換される。
'Python is {} {}'.format('Programming', 'Language')
# Python is Programming Language
引数の中に数値を入れると、位置を変更できる。
'Python {2} {1} {0}.'.format('Language', 'Programming', 'is')
# Python is Programming Language
キーワード引数を指定することもできる。
'Python {c} {b} {a}.'.format(a='Language', b='Programming', c='is')
# Python is Programming Language
辞書も可能。format()の引数に **
をつけると辞書の値を取得できる。
w = {'a' : 'apple', 'b' : 'banana', 'c' : 'cherry'}
fruits = '{a} {c}'
fruits.format(**w)
# 'apple cherry'
{0}
は format() への第一引数を表す。
w = {'a' : 'Apple', 'b' : 'Banana', 'c' : 'Cherry'}
'{0[a]} is not the same as {0[b]}.'.format(w)
# Apple is not the same as Banana.
f-string(f 文字列)
f-string は式を埋め込める文字リテラルである。先頭に f を付けて定義する。{}
の中では、演算子などの式を利用することができる。
w = 'world'
f'hello {w}'
# 'hello world'
w = 'world '
f'hello {w * 3}'
# 'hello world world world'
file_name = 'flower.jpg'
alt_name = '花の写真です'
f'<img src="{file_name}" alt="{alt_name}">'
# <img src="flower.jpg" alt="花の写真です">
リストの要素を返すこともできる。
img = ['flower.jpg', '花の写真です']
f'<img src="{img[0]}" alt="{img[1]}">'
# <img src="flower.jpg" alt="花の写真です">
w = ['apple', 'banana', 'cherry']
f'{w[1].title()}'
# 'Banana'
式を複数入れられる。
w = ['apple', 'banana', 'cherry']
f'{w[0].capitalize()} is not the same as...{w[1].rjust(20)}.'
# 'Apple is not the same as... banana.'
len()
組み込み関数である len() を使うと文字列内の文字数を数えることができる。
w = 'word'
len(w)
# 4
split()
組み込み関数である split() は、セパレータに基づき分割しリストに格納する。
w = 'a-b-c'
w.split('-') #分割して配列に格納
# ['a', 'b', 'c']
w = 'Lorem ipsum, dolor sit amet, consectetur adipisicing, elit'
w.split(',')
# ['Lorem ipsum', ' dolor sit amet', ' consectetur adipisicing', ' elit']
join()
join()関数は、シーケンス(list, tuple, range)のリストを一つの文字列に結合する。split()関数の逆と考えるとよい。
w = ['A', 'B', 'C', 'D']
print(' to the '.join(w))
# A to the B to the C to the D
strip()
strip()関数は文字列の先頭と末尾の文字を削除する。単語の間にあるものは削除しない。引数が指定されてないと、スペースや改行を取り除く。
w = ' abcd '
w.strip()
# abcd
w = '<p>hello</p>'
w.strip('<p></p>')
# 'hello'
w = 'http://example.com'
w.strip('http://')
# example.com
指定した先頭と末尾の記号を除去する。文字列の中にあるものはそのままだ。
w = '....abcd...efg...hijk....'
w.strip('.')
# 'abcd...efg...hijk'
rstrip()は右だけ、lstrip()は左だけ除去する。
w = ' abcd '
w.lstrip()
# 'abcd '
find()
部分文字列のオフセット(※ 3)を探すメソッドは、find() と index() である。find()は、指定した文字が見つからなければ -1 を返すが、index() は例外を返す。
find()は、部分文字列が見つかった場所の一番左のインデックスを返し、見つからなければ -1 を返す。find メソッドはブール値を返さない。find が 0 を返せば文字列の最初に検索対象があるということである。
w = 'abcde abcde abcde abcde abcde'
w.find('d')
# 3
w = 'abcde fghi jk lmn opqrstu'
w.find('lmn')
# 14
w = 'abcde fghi jk lmn opqrstu'
w.find('de')
# 3
w.find('z')
# -1
index()
index()は、対象の文字列が存在しないときに、例外を吐く。
'abcdefghijklmn'.index('e') # 検索する
# 4
w = 'abcde abcde abcde abcde abcde'
w.index('z')
# ValueError: substring not found
in 演算子
in 演算子を使うと、文字列の中に、指定した文字列が含まれているかどうかをブール値(False および True)で判定することができる。not in は、含まないという意味である。
'lo' in 'hello'
# True
'hello' not in 'z' # not in は、含まないという意味
# True
count()
count() は、文字のシーケンスがいくつ含まれているか数える。
'hello'.count('l') # 指定した文字を数える
# 2
capitalize()
capitalize() は先頭の文字を大文字に変換して返す。
'abcde'.capitalize()
# 'Abcde'
title()
title() は、単語の先頭文字を全て大文字に変換して返す。
'python is a general-purpose programming language.'.title()
# 'Python Is A General-Purpose Programming Language.'
upper()、lower()、swapcase()
upper()は、全ての文字を大文字に変換する。lower()を使うと、全ての文字が小文字になる。swapcase() は大文字と小文字を逆に変換する。
'python is programming language.'.upper()
# 'PYTHON IS PROGRAMMING LANGUAGE.'
'Python Is Programming Language.'.lower()
# 'python is programming language.'
'Python Is Programming Language.'.swapcase()
# 'pYTHON iS pROGRAMMING lANGUAGE.'