9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python組み込み型の勉強:文字列(str)

Last updated at Posted at 2019-01-21

メソッド一覧

# In
[v for v in dir('') if not v.startswith('_')]

# Out
['capitalize',
 'casefold',
 'center',
 'count',
 'encode',
 'endswith',
 'expandtabs',
 'find',
 'format',
 'format_map',
 'index',
 'isalnum',
 'isalpha',
 'isascii',
 'isdecimal',
 'isdigit',
 'isidentifier',
 'islower',
 'isnumeric',
 'isprintable',
 'isspace',
 'istitle',
 'isupper',
 'join',
 'ljust',
 'lower',
 'lstrip',
 'maketrans',
 'partition',
 'replace',
 'rfind',
 'rindex',
 'rjust',
 'rpartition',
 'rsplit',
 'rstrip',
 'split',
 'splitlines',
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

各メソッドの挙動

capitalize

先頭の単語の最初の文字だけを大文字にし、残りを小文字にする。

# In
'foo Bar BAZ'.capitalize()

# Out
'Foo bar baz'

casefold

特殊な文字(合字等)も含めて可能な限り小文字に変換する。

# In
'A B ß'.casefold()  # 半角A, 全角B, エスツェット(合字)

# Out
'a b ss'

lowerとは結果が異なる場合がある。

# In
'A B ß'.lower()

# Out
'a b ß'

center

指定桁数になる様に中央揃えする。

# In
[s.center(10, '_') for s in ['a', 'bb', 'ccc']]

# Out
['____a_____', '____bb____', '___ccc____']

パディング文字が省略された場合は半角スペースでパディングされる。

# In
[s.center(10) for s in ['a', 'bb', 'ccc']]

# Out
['    a     ', '    bb    ', '   ccc    ']

count

指定された文字列の出現回数を教えてくれる。

# In
'aaaaaaaaaa'.count('aa')

# Out
5

カウントを始める開始位置と終了位置を指定できる。

# In
'aaaaaaaaaa'.count('aa', 4)

# Out
3

# In
'aaaaaaaaaa'.count('aa', 4, 6)

# Out
1

encode

文字列(str)をバイト列(bytes)に変換する。

# In
'こんにちは、世界'.encode()

# Out
b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf\xe3\x80\x81\xe4\xb8\x96\xe7\x95\x8c'

文字コードの変換ができる。

# In
'こんにちは、世界'.encode('sjis')

# Out
b'\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x81A\x90\xa2\x8aE'

文字コードを指定する場合、第二引数にreplaceignoreを指定することで変換できない文字列を置換、あるいは無視できる。

この特性を利用することで特定の文字コードで使用できない文字を除去することができる。

入力がUTF-8なのにDBがSJISなシステムの開発をするときに役立った。

# In
'あ俠い'.encode('sjis', 'replace').decode('sjis')

# Out
'あ?い'  # ?で置換される
# In
'あ俠い'.encode('sjis', 'ignore').decode('sjis')

# Out
'あい'  # 除去される

第二引数を指定しないとUnicodeEncodeError例外が起きる。

# In
try:
    'あい俠うえ'.encode('sjis')
except UnicodeEncodeError as e:
    print(f'{e.start+1}文字目に{e.encoding}で使えない文字が含まれています')

# Out
3文字目にshift_jisで使えない文字が含まれています

endswith

指定された文字列で終わっていればTrueを、そうでなければFalseを返す。

# In
'aabbcc'.endswith('cc')

# Out
True

タプルを渡せる(リストは使えない)。

# In
'aabbcc'.endswith(('bb', 'cc'))

# Out
True

開始位置と終了位置(省略可)を指定できる。

# In
'aabbcc'.endswith('bb', 2, 4)

# Out
True

expandtabs

タブ文字を8桁の半角スペースに置換する。

# In
'a\tb\tc'.expandtabs()

# Out
'a       b       c'

任意の桁数を指定できる。

# In
'a\tb\tc'.expandtabs(4)

# Out
'a   b   c'

find

指定された文字列の最初の出現位置を教えてくれる。見つからなかった場合は-1を返す。

# In
'aabbcc'.find('bb')

# Out
2

探索開始位置と終了位置(省略可)を指定できる。

# In
'aabbcc'.find('bb', 0, 2)

# Out
-1

単に文字列が含まれているか知りたいのならinを使うべき by 公式ドキュメント

# Bad
if 'aabbcc'.find('bb') != -1:
    print('do something')

# Good
if 'bb' in 'aabbcc': 
    print('do something')

format

文字列の書式化を行う。

# In
name = '佐藤'
age = 18
'私の名前は{0}です、年齢は{1}歳です'.format(name, age)

# Out
'私の名前は佐藤です、年齢は18歳です'

Python3.6以降ならf-stringを使うと直感的に記述できる。

# In
name = '佐藤'
age = 18
f'私の名前は{name}です、年齢は{age}歳です'

# Out
'私の名前は佐藤です、年齢は18歳です'

パディングしたり演算したりと色々できる。

# In
name = '佐藤'
age = 18
f'私の名前は{name:_^10}です、年齢は{age/1.3:.8}歳です'

# Out
'私の名前は____佐藤____です、年齢は13.846154歳です'

format_map

dict等の辞書オブジェクトを使って文字列を書式化する。

# In
map_ = {'name': '佐藤', 'age': 18}
'私の名前は{name}です、年齢は{age}歳です'.format_map(map_)

# Out
'私の名前は佐藤です、年齢は18歳です'

カスタマイズした辞書ライクなオブジェクトを渡すと便利かもしれない。

# In
class MyMap(dict):
    PARAMS = {
        'name': '名前',
        'age': '年齢',
        'like': '趣味',
    }

    def __getitem__(self, key):
        if key not in self.PARAMS:
            return '[不明なパラメータ]'
        
        if key not in self:
            return f'[{self.PARAMS[key]}を入力してください]'
        
        return super().__getitem__(key)


mymap = MyMap()
mymap['name'] = '佐藤'
mymap['age'] = 18

'私の名前は{name}です、年齢は{age}歳です、趣味は{like}です、出身地は{born}です'.format_map(mymap)

# Out
'私の名前は佐藤です、年齢は18歳です、趣味は[趣味を入力してください]です、出身地は[不明なパラメータ]です'

index

基本はfindと同じで指定された文字列の最初の出現位置を教えてくれる。

# In
'aabbcc'.index('bb')

# Out
2

見つからなかった場合にValueError例外が起きるのがfindと異なる。

# Int
'aabbcc'.index('zz')

# Out
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-170-7650e5585328> in <module>
----> 1 'aabbcc'.index('zz')

ValueError: substring not found

isalnum

長さが1以上、かつ英数字のみで構成されているならTrueを、そうでなければFalseを返す。

# In
''.isalnum()

# Out
False
# In
'aA1'.isalnum()

# Out
True
# In
' a1 '.isalnum()

# Out
False

ただし、日本語を含む全角文字もTrueとして判断されてしまうので実際は正規表現を使ったほうが良い。

# In
'あいうえお'.isalnum()

# Out
True

isalpha

isalnumから数字部分を取り除いたと思えばOK。

# In
'aA1'.isalpha()

# Out
False
# In
'aA'.isalpha()

# Out
True
# In
'あいうえお'.isalpha()

# Out
True

isdecimal, isdigit, isnumeric

長さが1以上、かつ数字のみならTrueを、それ以外ならFalseを返すメソッド達。

ただし、半角数字以外にもTrueを返す場合があるので注意が必要。

def f(n):
    print([n.isdecimal(), n.isdigit(), n.isnumeric()])


# In
f('1')  # 半角

# Out
[True, True, True]

# In
f('')  # 全角

# Out
[True, True, True]

# In
f('')  # 丸数字

# Out
[False, True, True]

# In
f('')  # アラビア数字

# Out
[False, False, True]

# In
f('')  # 漢数字

# Out
[False, False, True]

isidentifier

Pythonの変数名として使えるならTrue、そうでなければFalseを返す。

正確な定義は公式ドキュメントを参照。

# In
'a'.isidentifier()

# Out
True

# In
''.isidentifier()

# Out
True

実際、日本語を変数名として使える。

# In
 = 100
 / 2

# Out
50.0

islower

大文字小文字の区別が出来る文字が1文字以上含まれ、それら全てが小文字ならばTrueを、そうでなければFalseを返す。

空白文字や日本語は区別が無いので無視されるが、区別が無い文字だけの場合はFalseが返る。

# In
'abcあいう \n\t'.islower()

# Out
True

# In
'あいう \n\t'.islower()

# Out
False

isprintable

文字列が空か、その全てが印字可能ならTrueを、それ以外ならFalseを返す・・・とのこと。

# In
'a'.isprintable()

# Out
True

改行文字は印字不可能らしい。

# In
'\n'.isprintable()

# Out
False

isspace

長さが1以上、かつ全て空白文字(タブや改行も含む)で構成されているならTrueを、そうでなければFalseを返す。

# In
' \t \n \r\n'.isspace()

# Out
True

istitle

The Endの様に、先頭のみ大文字の単語の組み合わせならTrueを、それ以外ならFalseを返す。

# In
'Gone With The Wind'.istitle()

# Out
True

日本語と英字を組み合わせた場合、日本語部分は無視される。

# In
'風と共に去りぬ - Gone With The Wind -'.istitle()

# Out
True

日本語のみの場合はFalseが返る。

# In
'風と共に去りぬ'.istitle()

# Out
False

isupper

大文字小文字の区別が出来る文字が1文字以上含まれ、それら全てが大文字ならばTrueを、そうでなければFalseを返す。

空白文字や日本語は区別が無いので無視されるが、区別が無い文字だけの場合はFalseが返る。

# In
'ABCあいう \n\t'.isupper()

# Out
True

# In
'あいう \n\t'.isupper()

# Out
False

join

リスト等のiterableなオブジェクトの全要素を指定された文字列で連結する。

# In
','.join(['foo', 'bar', 'baz'])

# Out
'foo,bar,baz'

# In
' >>> '.join(['foo', 'bar', 'baz'])

# Out
'foo >>> bar >>> baz'

連結文字は省略可能。

# In
''.join(['foo', 'bar', 'baz'])

# Out
'foobarbaz'

文字列もiterableなのでjoinできる。

# In
'-'.join('foobarbaz')

# Out
'f-o-o-b-a-r-b-a-z'

ljust

指定桁数になる様にパディング文字で左詰めする。パディング文字が省略された場合は半角スペースでパディングされる。

# In
'foo'.ljust(10, '_')

# Out
'foo_______'

# In
'foo'.ljust(10)

# Out
'foo       '

lower

全ての大文字を小文字に変換する。全角大文字の場合は全角小文字に変換される。

# In
'A A'.lower()  # 半角, 全角

# Out
'a a'  # 半角, 全角

lstrip

先頭にある空白文字(全角スペースや改行等を含む)を全て削除する。

# In
' \u3000\t\n\r\nfoo \u3000\t\n\r\n'.lstrip()

# Out
'foo \u3000\t\n\r\n'

削除する文字を指定する事もできる。指定されていない文字にぶつかった時点で処理がストップする。

# In
' <#!# foo ##> '.lstrip(' <#')

# Out
'!# foo ##> '  # !以降は除去されない

str.maketrans, translate

変換テーブルを使った文字置換を行う。

以下は0〜4の数字を*に置換し、5〜9は削除する例。

# In
# 変換テーブルとなる辞書を作成
mapping = dict.fromkeys('01234', '*')
mapping.update(dict.fromkeys('56789', None))  # 削除したい場合はNoneを指定
print('mapping:', mapping)

# translateが扱える形式に変換
table = str.maketrans(mapping)
print('table:', table)
print('type(table):', type(table))

# 変換する
print('\ntranslated: a1b2c3d4e5f6g7h8i9'.translate(table))

# Out
mapping: {'0': '*', '1': '*', '2': '*', '3': '*', '4': '*', '5': None, '6': None, '7': None, '8': None, '9': None}
table: {48: '*', 49: '*', 50: '*', 51: '*', 52: '*', 53: None, 54: None, 55: None, 56: None, 57: None}
type(table): <class 'dict'>

translated: a*b*c*d*efghi

辞書を使わない変換も可能。以下の例ではh->H l->L o->O ,!は削除という変換が行われる。

# In
table = str.maketrans('hlo', 'HLO', ',!')
'hello, world!'.translate(table)

# Out
'HeLLO wOrLd'

partition

指定文字列が最初に見つかった位置で文字列を分割する。結果は要素数3のタプルとして返ってくる。

# In
'foo//bar//baz'.partition('//')

# Out
('foo', '//', 'bar//baz')

分割文字列が含まれない場合は先頭以外空のタプルが返ってくる。

# In
'foo//bar'.partition('+')

# Out
('foo//bar', '', '')

replace

文字列に含まれる特定文字を指定文字に置換する。

# In
'hello, world!'.replace('l', '*')

# Out
'he**o, wor*d!'

置換する回数を指定できる。

# In
'hello, world!'.replace('l', '*', 1)

# Out
'he*lo, world!'

文字列の置換は出来るが、1文字としてまとめられてしまう。

# In
'hello, world!'.replace('lo', '*')

# Out
'hel*, world!'  # he***, w*r*d! とはならない

rfind

指定された文字列の最後の出現位置を教えてくれる(findは最初の位置)。見つからなかった場合は-1を返す。

# In
'aabbccaa'.rfind('aa')

# Out
6

findと同様に探索位置を指定できる。

# In
'aabbccaa'.rfind('aa', 0, 4)

# Out
0

rindex

基本はrfindと同じで指定された文字列の最後の出現位置を教えてくれる。

# In
'aabbccaa'.rindex('aa')

# Out
6

見つからなかった場合にValueError例外が起きるのがfindと異なる。

# Int
'aabbccaa'.rindex('zz')

# Out
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-401-8aa97a6819ae> in <module>
----> 1 'aabbccaa'.rindex('zz')

ValueError: substring not found

rjust

指定桁数になる様にパディング文字で右詰めする。パディング文字が省略された場合は半角スペースでパディングされる。

# In
'foo'.rjust(10, '_')

# Out
'_______foo'

# In
'foo'.rjust(10)

# Out
'       foo'

rpartition

指定文字列が最後に見つかった位置で文字列を分割する(partitionは最初の位置で分割)。結果は要素数3のタプルとして返ってくる。

# In
'foo//bar//baz'.rpartition('//')

# Out
('foo//bar', '//', 'baz')

分割文字列が含まれない場合は最後以外空のタプルが返ってくる。

# In
'foo//bar'.partition('+')

# Out
('', '', 'foo//bar')

rsplit

空白文字(全角スペースや改行等を含む)、あるいは指定された文字列で分割する。

# In
'a b\u3000c\td\ne'.rsplit()

# Out
['a', 'b', 'c', 'd', 'e']

連続している場合も正しく分割してくれる。

# In
'a  b\t\tc'.rsplit()

# Out
['a', 'b', 'c']

分割文字を指定した場合は文字列として一致した場合のみ分割する。分割文字列が2回以上連続する場合は空白として分割される。

# In
'foo//bar/baz//////qux'.rsplit('//')

# Out
['foo', 'bar/baz', '', '', 'qux']

分割する回数を指定できる。rsplitの場合は末尾から分割される。

# In
'foo/bar/baz'.rsplit('/', 1)

# Out
['foo/bar', 'baz']

rstrip

末尾にある空白文字(全角スペースや改行等を含む)を全て削除する。

# In
' \u3000\t\n\r\nfoo \u3000\t\n\r\n'.rstrip()

# Out
' \u3000\t\n\r\nfoo'

削除する文字を指定する事もできる。指定されていない文字にぶつかった時点で処理がストップする。

# In
' <## foo ##> ! ##'.rstrip(' >#')

# Out
' <## foo ##> !'  # !以前は除去されない

split

基本はrsplitと同じで、空白文字で文字列を分割する。

# In
'a b\u3000c\td\ne'.split()

# Out
['a', 'b', 'c', 'd', 'e']

分割回数を指定した場合に先頭から分割される点が異なる。

# In
'foo/bar/baz'.split('/', 1)

# Out
['foo', 'bar/baz']

splitlines

改行文字(\n, \r, \r\nで分割する。

# In
'line1\nline2\rline3\r\n'.splitlines()

# Out
['line1', 'line2', 'line3']

第二引数に1以上の整数かTrueを渡すと改行文字を維持してくれる。

# In
'line1\nline2\rline3\r\n'.splitlines(True)

# Out
['line1\n', 'line2\r', 'line3\r\n']

startswith

指定された文字列で終わっていればTrueを、そうでなければFalseを返す。

# In
'aabbcc'.startswith('aa')

# Out
True

タプルを渡せる(リストは使えない)。

# In
'aabbcc'.startswith(('aa', 'bb'))

# Out
True

開始位置と終了位置(省略可)を指定できる。

# In
'aabbcc'.startswith('bb', 2, 4)

# Out
True

strip

前後にある空白文字(全角スペースや改行等を含む)を全て削除する。

# In
' \u3000\t\n\r\nfoo \u3000\t\n\r\n'.strip()

# Out
'foo'

削除する文字を指定する事もできる。指定されていない文字にぶつかった時点で処理がストップする。

# In
'<## ! ## foo ## ! ##>'.strip(' <>#')

# Out
'! ## foo ## !'  # !より内側は除去されない

swapcase

大文字は小文字に、小文字は大文字に変換する。

# In
'foo Bar BAZ'.swapcase()

# Out
'FOO bAR baz'

title

The Endの様に、各単語の先頭のみ大文字に、それ以外を小文字にする。

# In
'foo Bar BAZ'.title()

# Out
'Foo Bar Baz'

upper

全ての小文字を大文字に変換する。全角小文字の場合は全角大文字に変換される。

# In
'a a'.upper()  # 半角, 全角

# Out
'A A'  # 半角, 全角

zfill

指定された長さになる様に0で右詰めする。

# In
'100'.zfill(9)

# Out
'000000100'

先頭が+-の符号で始まる場合、符号込みで指定された長さにする。

# In
'-100'.zfill(9)

# Out
'-00000100'  # 0は5個

特定の文字列が含まれるかチェック

inで簡単にチェックできる。

# In
'bar' in 'foo bar baz'

# Out
True

長い文字列の宣言

バックスラッシュで連結

s1 = 'ちょっと長い、\
けっこう長い、\
かなり長い、\
文字列の宣言'

トリプルクオート(ヒアドキュメント)

'''もしくは""" を使えばバックスラッシュ無しで記述できる。改行も含まれてしまう点に注意。

s2 = '''ちょっと長い、
けっこう長い、
かなり長い、
文字列の宣言'''

半角スペースで連結

s3 = 'ちょっと長い、' 'けっこう長い、' 'かなり長い、' '文字列の宣言'

括弧()``[]``{}

インデント出来るので可読性が高い。

s4 = (
    'ちょっと長い、'  # カンマをつけるとtupleになってしまうので注意
    'けっこう長い、'
    'かなり長い、'
    '文字列の宣言'
)
s5 = [
    'ちょっと長い、'
    'けっこう長い、'
    'かなり長い、'
    '文字列の宣言'
].pop()
s6 = {
    'msg': 'ちょっと長い、'
           'けっこう長い、'
           'かなり長い、'
           '文字列の宣言'
}['msg']

関数にも渡しやすいので個人的には括弧を多用する。

# In
def replace(s, old, new):
    return s.replace(old, new)

    
replace('hello, '
        'world!',
        'lo',
        '*')

# Out
'hel*, world!'

任意回数繰り返す

テストを書く際に多用する。

# In
'foo' * 10

# Out
'foofoofoofoofoofoofoofoofoofoo'

シーケンス操作

strはiterableなのでlistと同様のシーケンス操作が可能。

ループ処理

# In
for i, v in enumerate('abc'):
    print(i, v)

# Out
0 a
1 b
2 c

長さの取得

# In
len('abc')

# Out
3

展開(アンパック)

# In
a, b, *c = 'abcdefg'
print(a, b, c)

# Out
a b ['c', 'd', 'e', 'f', 'g']

スライス

インデックス指定によるスライス操作が可能。

先頭の文字を取得

'abcd'[0]  # 'a'

最後の文字を取得

'abcd'[-1]  # 'd'

n文字目以降を取得

'abcd'[2:]  # 'cd'

n文字目までを取得

'abcd'[:2]  # 'ab'

n~m文字目を取得

'abcd'[1:3]  # 'bc'

n文字飛ばしで取得

'abcd'[::2]  # 'ac'

'abcdefgh'[::4]  # 'ae'

反転する

正確には末尾から一文字ずつ取得させている。

'abcd'[::-1]  # 'dcba'

iterableを処理する関数に渡す

iterableなオブジェクトを引数に取る関数に渡せる。

 # In
dict(zip('abc', [1,2,3]))

# Out
{'a': 1, 'b': 2, 'c': 3}
9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?