01 / 07
言葉では言い表せない探しもの
第2章で in や find を覚えたね。あれは「この言葉があるか」を調べる道具だった。
でも、探したいものがいつも言葉で言えるとは限らないよ。
- 「数字がならんでいるところ」
- 「郵便番号っぽい形をしたところ」
- 「ひらがなだけが続いているところ」
これは言葉ではなく形だね。形を書き表すための書きかたを 正規表現(せいきひょうげん)と呼ぶよ。
もっと便利な道具
INPUT · スライド
01 / 07
第2章で in や find を覚えたね。あれは「この言葉があるか」を調べる道具だった。
でも、探したいものがいつも言葉で言えるとは限らないよ。
これは言葉ではなく形だね。形を書き表すための書きかたを 正規表現(せいきひょうげん)と呼ぶよ。
02 / 07
正規表現は re(アールイー)というモジュールに入っている。第6章でやった import で読みこもう。
いちばんよく使うのが re.search。「その形がどこかにあるか」を探して、見つかった部分を返してくれるよ。
r"\d+" が「形」の部分。\d が数字1文字、+ が1個以上という意味だから、あわせて「数字が1個以上ならんだところ」だね。
import remoji = "でんわは09012345678です"m = re.search(r"\d+", moji)if m: print(m.group())実行結果
09012345678
03 / 07
形を書くときは、クォートの前に r を付ける。これは raw(ロウ、生の)という意味だよ。
ふつうの文字列では、\n が「改行1文字」に化けてしまう。バックスラッシュが特別な合図として食べられてしまうんだ。
r を付けると、そういう読みかえをやめて書いたままの2文字として渡してくれる。正規表現はバックスラッシュを山ほど使うので、r を付けるのが決まりだと思っておこう。
print(r"\n")print(len(r"\n"))print(len("\n"))実行結果
\n 2 1
04 / 07
正規表現には記号がたくさんあるけれど、この章で扱うのは下の9つだけだよ。
| 記号 | 意味 |
|---|---|
\d | 数字1文字 |
\w | 文字1文字(英数字・かな・漢字) |
. | なんでも1文字 |
+ | 直前が1個以上 |
* | 直前が0個以上 |
{3} | 直前がちょうど3個 |
[あ-ん] | この範囲のどれか1文字 |
^ | 先頭 |
$ | 末尾 |
全部覚える必要はない。「こういうものがある」と知っていて、必要なときに調べられれば十分だよ。
import reprint(re.findall(r"\d+", "りんご3こ みかん12こ"))print(re.findall(r"[あ-ん]+", "りんご3こ"))実行結果
['3', '12'] ['りんご', 'こ']
05 / 07
ここがいちばん大事なところ。re.search は見つからなかったとき None を返すよ。
エラーにはならない。静かに None が返ってくるだけだ。第1章でやった「値が無いということ」が、ここで効いてくるんだ。
import rem = re.search(r"\d+", "すうじはありません")print(m)実行結果
None
06 / 07
None に group() は無い。確かめずに呼ぶと落ちるよ。
だから正規表現を使うときは、必ず if m: ではさむ。これがお決まりの形だよ。
m = re.search(r"\d+", moji)if m: print(m.group())この3行を指が覚えるまで書こう。見つからないかもしれないものを扱うときの、基本の作法だよ。
import rem = re.search(r"\d+", "すうじはありません")print(m.group())実行結果
AttributeError: 'NoneType' object has no attribute 'group'
07 / 07
re.search の仲間があと2つあるよ。
re.findall … 当てはまるところを全部集めて、文字のリストで返す。見つからなければ空のリストre.match … 先頭から当てはまるかだけを見る。途中にあっても見つけてくれないfindall はリストが返るので group() が要らない。いちばん気楽に使えるのはこれだよ。
次のレッスンでは、見つけた部分をさらに分けて取り出す書きかたを覚えよう。
import reprint(re.findall(r"\d+", "a1b22"))m = re.match(r"\d+", "123あ")if m: print(m.group())print(re.match(r"\d+", "あ123"))実行結果
['1', '22'] 123 None