Lesson11 文字列の操作

イメージ画像

文字列についてあらためて学ぼう

  • 文字の長さを取得する
  • 文字列からリストを作る
  • 文字の部分を取得する
  • あるパターンが文字列に含まれるか判定する
  • ある文字列を別の文字列で置換する

本日は、あらためて文字列について学びます。

今使うソースコードはここからまとめてダウロードできます。 ダウンロードfile_download

前回の復習

前回Lesson10は復習回でTurtleでひし形模様を描きました。ひし形模様ではifでなく関数で分岐することも学びましたね。
また。その前のLesson09では、グラフを描く方法を学びました。

前回出た重要キーワード

  • import matplotlib.pyplot as plt でグラフを描く方法
  • 散布図を描く方法
  • 散布図のプロットした点を線で結ぶ方法
  • 数学関数のグラフをを描く方法

1文字列の操作

この章のキーワード

  • len関数
  • split
  • 文字の部分を取得する方法(スライス)
  • re.search
  • re.findall
  • 正規表現、パターン

1.1 文字とは何かとあらためて print 関数

文字は python では " と " で囲まれるか ' と ' で囲まれます。
 1
 2
suuji = '123' #文字
suuji2 = 123  #数字

print 関数を改めて復習しましょう。

改行の有無

改行したくない場合は

print("表示したい文字",end=行末の文字)

lesson_0011_1.py

 1
 2
 3
 4
bun = '吾輩はねこである。'
bun2 = '名前はまだない。'
print(bun,end="")
print(bun2)

実行結果

1 吾輩はねこである。名前はまだない。

また、改行したい場合は、\n を使います。

lesson_0011_2.py

 1
 2
bun = '吾輩はねこである。\n名前はまだない。'
print(bun)

実行結果

 1
 2
吾輩はねこである。
名前はまだない。

1.2 文字の長さを取得する

文字列の長さを取得するには len 関数を使います。

文字の長さ

文字の長さ = len(文字、文字を入れた変数)

文字の長さは、len関数で求めます。

lesson_0011_10.py

 1
 2
bun = '吾輩はねこである。'
print(len(bun))

実行結果

1 9

1.3 文字列からリストをつくる(文字列を分割してリスト化)

文字列をある区切り文字列(デリミタと言います)で分割するときは、split を使います。
Lesson7 の P11 で既に学習しました。

リストを格納する変数 = 分割したい文字列 . split(区切り文字列)
文字列を分割してリスト化ソース(lesson_0011_20.py)
1
2
3
4
5
6
7
8
9
10
11
mojiretsu = "1 3 5 7"

suuji = mojiretsu.split(' ')
suuji[0] = int(suuji[0])
suuji[1] = int(suuji[1])
suuji[2] = int(suuji[2])
suuji[3] = int(suuji[3])

print("この数字の平均は")
print(sum(suuji)/4)
print("です")

実行結果

 1
 2
 3
 4
 5
この中の平均は
6
です

1.4 文字の部分を取得する

実は、文字は配列の一種です。リストと似た扱いをすることができます。

文字列の第 N 文字目を取り出す方法

文字列を格納した変数[N]

文字列の第 N 文字目から K 番目の直前(つまり K-1 番目)までを取り出す方法

文字列を格納した変数[N:K]

このような指定方法をスライスといいます。

次の文字をスライスで部分文字列と取り出してみましょう。

str = “吾輩はねこである。名前はまだない。”


                  0     1     2    3     4     5    6    7  8       9   10   11  12  13  14  15 16

lesson_0011_30.py

 1
 2
 3
bun = '吾輩はねこである。'
print(bun[4])
print(bun[3:5])

実行結果

 1
 2
こ
ねこ

1.5 文字にあるパターンが含まれているかどうか判断する

文字列の中にあるパターンがあるかどうかを見つけるには、re モジュールを使います。

re.search(r'含まれている文字', あるパターンを探す文字列) が True を返す

lesson_0011_40.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
import re

bun = 'ニワには二羽ニワトリがいる。'
pattern = 'ニワ'
match = re.search(pattern, bun)
if match :
    print("この文字には「"+pattern+"」という単語が入っています。")
else:
    print("この文字には「"+pattern+"」という単語は見つかりません。")

実行結果

1 この文字には「ニワ」という単語が入っています

search の 1 番目の引数は正規表現と言われるパターンを指定する方法でパターンを見つけることもできます。

以下は与えられた文字列の中に 0A0-XXXX-XXXX という携帯電話の番号と推測される文字列部分を見つけ、その携帯電話の中 4 桁を取り出すというプログラムです。3行目に理解できない呪文のようなものがありますね。これは正規表現というもので、今は理解できなくてもかまいません。こんなことができるんだ、程度に覚えておいてください。

lesson_0011_41.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
import re
bun = '私の自宅の電話番号は 03-1234-5678 です。携帯電話は、090-9876-5432 です。弟の携帯は 070-1111-2222 です。'
match = re.findall(r'((0[7|8|9]0)\-(\d{4})\-(\d{4}))', bun)

if match :
    for str in match :
        print("携帯電話の中4桁が見つかりました:"+str[2])
else:
    print("携帯電話番号は見つかりません。")

実行結果

 1
 2
携帯電話の中4桁が見つかりました:9876
携帯電話の中4桁が見つかりました:1111

1.6 ある文字列を別の文字列で置換する

置き換え後の文字 = 文字列.replace(置き換えられる文字部分,新しく置き換える文字)

lesson_0011_50.py

 1
 2
 3
bun = 'にわには二羽にわとりがいる'
bun = bun.replace('にわ','庭')
print(bun)

実行結果

1 庭には二羽庭とりがいる

2か所ある「にわ」の文字が「庭」に置き換わっています。

演習の時間

演習の解答はここからダウンロードできます。ダウンロードfile_download

演習1

名前の一部から総理大臣を見つける簡単な検索システムを作ってみましょう。
これは、名前の一部からその一部の文字を含む総理大臣の名前と第何代かを表示します。
キーボードから含まれる文字を入力します。
なお、ある文字 X を含むかどうかの正規表現パターンは ’.*X.*’ です。

期待される動作(名前に「藤」の文字が含まれる総理大臣を検索した場合)

検索したい文字を入力してください。

藤の文字が入った人は: 第1代総理大臣の伊藤博文
藤の文字が入った人は: 第5代総理大臣の伊藤博文
藤の文字が入った人は: 第7代総理大臣の伊藤博文
藤の文字が入った人は: 第10代総理大臣の伊藤博文
藤の文字が入った人は: 第21代総理大臣の加藤友三郎
藤の文字が入った人は: 第24代総理大臣の加藤高明
藤の文字が入った人は: 第30代総理大臣の齋藤 實
藤の文字が入った人は: 第61代総理大臣の佐藤榮作
藤の文字が入った人は: 第62代総理大臣の佐藤榮作
藤の文字が入った人は: 第63代総理大臣の佐藤榮作

enshu_0011_1.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import re
president = [
  "",
  '伊藤博文',
  '黒田清隆',
  '山縣有朋',
・・・
]
print("検索したい文字を入力してください。") moji = input() pattern = '.*' + moji +'.*' # ここは別の機会に解説します。正規表現と言います
for k, name in enumerate(president):   m = ???? if m : print(moji + "の文字が入った人は: "+str(k)+"第総理大臣の"+name)

演習2

先生から与えられた jp_name.py は日本の苗字の全国 1 位から 3000 位までがおよその人口別にリストになっています。第 1 位は佐藤で、全国で 18 万 6200 人ほどいるようです。
from jp_name import jp_name を先頭で宣言してください。

 1
 2
 3
 4
 5
jp_name =[
    "1",    "佐藤","1862000",
    "2",    "鈴木","1791000",
…
] 

【演習1】を改造し、文字列を入力して、その文字列を含む苗字が3000 位以内ならその順位を、3000位に入っていなければ「ランク外です」と表示するプログラムを書きましょう。
またその苗字を持っている人が日本の国の全体の何パーセントくらいか調べてみましょう。日本の総人口は 1 億 2600 万人とします。

期待される動作(名前に「山本」の文字が含まれる人を検索した場合)

順位を調べたい苗字を入力してください。
山本
山本の苗字を持つ人は全国 7位で総人口の約 0.829 %です
終了します。

また、何度も実行するのはめんどくさいので、単に Enter を押せば終了し、押さなければなんども調べたい苗字を聞くようにしてください。
whileを使いましょう。プログラムを終了するときは、 whileを抜けるにようにしてみましょう。
下の「プログラムの出だし」から続けてみましょう。patternについては、まだ習っていない正規表現というものです。これについてはこのまま写してください。

ヒントプログラムの出だし

 1
 2
 3
 4
 5
 6
from jp_name import jp_name
import re

print("検索したい文字を入力してください。")
moji = input()
pattern = '.*' + moji +'.*'

時間があまったあなたに

この演習の正規表現や授業中であつかった電話番号の正規表現は理解する必要はありませんが、もし興味があればインターネットなどで調べてみましょう。
正規表現は、多くのエディタに搭載されている機能で、使い方を覚えると文章において大量の文字列を置き換えるといった作業が簡単にできるようになります。

また、正規表現そのものも奥深い理論で、オートマトン理論という形式言語を研究する分野で研究されています。もし、将来、プログラミング言語を自分で作ろうと思ったら、正規表現やオートマトン理論という単語に出会うでしょう。