8. 文字列#

8.1. 基本#

文字列はシングルクォーテーション(')、またはダブルクォーテーション(")で囲む。代入文により、変数に文字列への参照が代入される。なお、C言語における文字型charに相当するものはない。

s = 'stress'
s
'stress'
type(s)
str

文字列の長さ(文字数)はlen関数で取得できる。

len(s)
6

文字列はユニコード文字列として表現されているため、日本語の文字列も問題なく表現できる。

s = 'ストレス'
len(s)
4

空文字列は''str関数で作成できる。

s = ''
s
''
s = str()
s
''

8.2. 特殊文字や複数行にわたる文字列#

文字列において、\\n(改行文字)や\t(タブ文字)などの特殊文字を表現するためのエスケープ・シーケンスと解釈されるため、文字通りの解釈にはならない。

s = 'C:\Users\okazaki'
  File "/tmp/ipykernel_2667/1140256298.py", line 1
    s = 'C:\Users\okazaki'
        ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

\を文字として表現するには、\\とする。

s = 'C:\\Users\\okazaki'
print(s)
C:\Users\okazaki

文字列の先頭にrを書くことで、\がエスケープ・シーケンスの一部と解釈されず、文字通りに解釈される(raw string)。

s = r'C:\Users\okazaki'
print(s)
C:\Users\okazaki

文字列の中に'を含めるには、文字列全体をダブルクォーテーション(")で囲んでおくとよい。

s = "stress's"
s
"stress's"

シングルクォーテーション(')で囲まれた文字列の中でシングルクォテーション(')を含めるには、エスケープ・シーケンス\'を使う。

s = 'stress\'s'
s
"stress's"

複数行にわたる文字列を定義するには、"""を用いるとよい。

s = """先頭行
2行目
3行目"""
print(s)
先頭行
2行目
3行目
s
'先頭行\n2行目\n3行目'

8.3. 数値と文字列の間の変換#

数値から文字列への変換にはstr関数を用いる。ただ、ひとつの数値を文字列に変換するだけでなく、他の数値や文字列を一緒に文字列として表現するには、後述するフォーマット文字列が便利である。

x = 10
s = str(x)
s
'10'
x = 3.14
s = str(x)
s
'3.14'

文字列から数値への変換にはint関数を用いる。

s = '10'
x = int(s)
x
10
s = '3.14'
x = float(s)
x
3.14

数値から2進数形式の文字列への変換にはbin関数を用いる。

bin(255)
'0b11111111'

数値から16進数形式の文字列への変換にはhex関数を用いる。

hex(255)
'0xff'

8.4. インデックス、スライス#

文字列中の\(i\)番目(先頭は\(0\)番目)の文字を取り出す。

s = 'stressed'
s[0]
's'
s[1]
't'

文字列の範囲外の文字を取り出そうとすると、エラーになる。

s[8]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
/tmp/ipykernel_2667/495611267.py in <module>
----> 1 s[8]

IndexError: string index out of range

末尾の文字を取り出す。

s[len(s)-1]
'd'

負のインデックス\(-i\)は、文字列の末尾から数えて\(i\)番目の文字を取り出す。

s[-1]
'd'
s[-3]
's'

その他、スライスの使い方はリストと同様である。

s[0:3]
'str'
s[:3]
'str'
s[6:]
'ed'
s[:-2]
'stress'
s[-2:]
'ed'
s[:6:2]
'srs'
s[::2]
'srse'
s[::-1]
'desserts'

文字列は不変なオブジェクトであるため、その要素は変更することはできない(可変と不変を参照)。

s[3] = 'a'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_2667/2319426980.py in <module>
----> 1 s[3] = 'a'

TypeError: 'str' object does not support item assignment

8.5. 文字列に対する操作#

s = "https://www.nlp.c.titech.ac.jp/search?q=Natural+Language+Processing"

小文字への変換。

s.lower()
'https://www.nlp.c.titech.ac.jp/search?q=natural+language+processing'

大文字への変換。

s.upper()
'HTTPS://WWW.NLP.C.TITECH.AC.JP/SEARCH?Q=NATURAL+LANGUAGE+PROCESSING'

文字列の置換。

s.replace('search', 'find')
'https://www.nlp.c.titech.ac.jp/find?q=Natural+Language+Processing'

指定した文字列が最初に現れる場所(インデックス)を返す。

s.find('/')
6
s[:6]
'https:'
s[6:]
'//www.nlp.c.titech.ac.jp/search?q=Natural+Language+Processing'

指定した文字が見つからない場合は-1を返す。

s.find('html')
-1

指定した文字列が最後に現れる場所(インデックス)を返す。

s.rfind('/')
30
s[:30]
'https://www.nlp.c.titech.ac.jp'
s[30:]
'/search?q=Natural+Language+Processing'

指定した文字('+')で文字列を分割し、リストで表現する(なお、s[40:]'Natural+Language+Processing'である)。

v = s[40:].split('+')
v
['Natural', 'Language', 'Processing']

リストの要素を指定した文字('/')で連結する。

t = '+'.join(v)
t
'Natural+Language+Processing'

リストの要素を指定した文字(', ')で連結する。

', '.join(v)
'Natural, Language, Processing'

リストの要素をそのまま(空文字で)連結する。

''.join(v)
'NaturalLanguageProcessing'

先頭もしくは末尾に指定した文字(複数指定可)が付いているとき、それを取り除く。

s = '  one, two, three, '
s.strip(' ')
'one, two, three,'
s.strip(', ')
'one, two, three'

末尾に指定した文字(複数指定可)が付いているとき、それを取り除く。

s.rstrip(' ')
'  one, two, three,'
s.rstrip(',')
'  one, two, three, '
s.rstrip(', ')
'  one, two, three'

先頭に指定した文字(複数指定可)が付いているとき、それを取り除く。

s.lstrip(' ')
'one, two, three, '
s.lstrip(',')
'  one, two, three, '
s.lstrip(', ')
'one, two, three, '

8.6. 文字列に対する条件#

s = "Tokyo Institute of Technology 2020"

文字列の一致。

s == 'TokyoTech'
False

文字列の不一致。

s != 'TokyoTech'
True

辞書順による文字列の比較。

s < 'Tokyo Tech'
True
s > 'Tokyo Tech'
False

部分文字列を含むか。

'Tokyo' in s
True

部分文字列を含まないか。

'University' not in s
True

指定した文字列で始まるかどうかチェックする。

s.startswith('Tokyo')
True
s.startswith('Institute')
False

指定した文字列で終わるかどうかチェックする。

s.endswith('2020')
True
s.endswith('Technology')
False

(すべてが)大文字か。

s.isupper()
False
s[0].isupper()
True
s[1].isupper()
False

(すべてが)小文字か。

s.islower()
False
s[0].islower()
False
s[1].islower()
True

(すべてが)空白文字か。

s.isspace()
False
s[0].isspace()
False
s[5].isspace()
True

(すべてが)アルファベット文字か。

s.isalpha()
False
s[:5].isalpha()
True
s[:6].isalpha()
False

(すべてが)数字か。

s.isnumeric()
False
s[-4:].isnumeric()
True
'七十七'.isnumeric()
True
'七十七銀行'.isnumeric()
False

8.7. フォーマット文字列#

year = 2020
month = 'December'
date = 9
hour = 9
minute = 15
second = 43.3

8.7.1. printf形式の文字列書式化#

C言語風のprintf形式の文字列書式化は、%演算子で利用可能。ただし、Python 3ではあまり推奨されていない。

'%s %d, %d' % (month, date, year)
'December 9, 2020'
'%02d:%02d:%02.03f, %s %d, %d' % (hour, minute, second, month, date, year)
'09:15:43.300, December 9, 2020'

8.7.2. 書式指定文字列#

Python 3では、書式指定文字列str.formatメソッド)が用いられる。変数の値を文字列として埋め込みたい箇所を{}で囲う。値の型を指定しなくてもよい。

formatメソッドの引数の位置に応じて文字列に埋め込む。

'{1} {2}, {0}'.format(year, month, date)
'December 9, 2020'
'{2} {1}, {0}'.format(year, month, date)
'9 December, 2020'

引数の位置の指定を省略し、引数の先頭から順に{}を埋める。

'{} {}, {}'.format(month, date, year)
'December 9, 2020'

引数に名前を付け、その名前を書式指定文字列で参照する。

'{m} {d}, {y}'.format(y=year, m=month, d=date)
'December 9, 2020'

整数や浮動小数点数も型を指定せずに埋め込める。

'{}:{}:{}'.format(hour, minute, second)
'9:15:43.3'

整数や浮動小数点数の整形方法を指定。多くの場合、printf形式の文字列書式化の%の代わりに:に置き換えるだけで済む。例えば、%02.3f:02.3fとなる。

'{:02}:{:02}:{:02.3f}'.format(hour, minute, second)
'09:15:43.300'

8.7.3. フォーマット済み文字列リテラル#

フォーマット済み文字列リテラル(文字列の先頭にプレフィックスfまたはFを付ける)を使うと、formatメソッドを呼び出すことなく、アクセス可能な変数を参照できる。

f'{month} {date}, {year}'
'December 9, 2020'

書式指定を行い、数値の0埋めや桁数を揃える。

f'{hour:02}:{date:02}:{second:02.03f}, {month} {date}, {year}'
'09:09:43.300, December 9, 2020'

Pythonの式を直接書式指定に埋め込むこともできる。

f"{month[:3]} {date}, '{year % 2000}"
"Dec 9, '20"

8.8. 文字エンコーディング#

s = 'Python言語'

ユニコードで表現されている文字列を任意の文字コードでエンコードするには、encodeメソッドを用いる。バイト列と呼ばれる、バイナリデータを格納するオブジェクトが得られる。以下の例は、文字列sをUTF-8に変換する例である。

s.encode('utf8')
b'Python\xe8\xa8\x80\xe8\xaa\x9e'

同様に、文字列sをUTF-16に変換する例である。

s.encode('utf-16')
b'\xff\xfeP\x00y\x00t\x00h\x00o\x00n\x00\x00\x8a\x9e\x8a'

ある文字コードでエンコードされたバイト列から文字列を得る(デコードする)には、decodeメソッドを用いる。

b = b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e'
b.decode('utf8')
'日本語'