毎日ちょっとPython ~ 15日目 ~

ちょっとの定義を決めよう。きりの良さや、項目の後ろのほう見て決めたけど時間で区切る。

25minでどうだろう。

findall()メソッド

Regexオブジェクトには search() のほかに findall() があります。

search() - 最初に見つかった文字列のMatchオブジェクト
findall() - みつかったすべてのMatchオブジェクト

>>> phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
>>> mo = phone_num_regex.search('Cell: 415-555-09999 work: 212-555-0000')
>>> mo.group()
'415-555-0999'
>>> phone_num_regex.findall('Cell: 415-555-09999 work: 212-555-0000')
['415-555-0999', '212-555-0000']

findall()は正規表現にグループが含まれているとタプルのリストを返します

>>> phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)')
>>> phone_num_regex.findall('Cell: 415-555-09999 work: 212-555-0000')
[('415', '555', '0999'), ('212', '555', '0000')]

まとめると、findall()は

1. グループのない正規表現の場合はマッチした文字列のリストを返す。
例:['415-555-0999', '212-555-0000']

2. グループありの正規表現はグループに対応した文字列のタプルのリストを返す
例:[('415', '555', '0999'), ('212', '555', '0000')]

文字集合

覚えておくだけ

\d - 0~9の数字
\D - 0~9の数字以外
\w - 文字、数字、下線
\W - 文字、数字、下線以外
\s - スペース、タブ、改行
\S - スペース、タブ、改行以外

たとえば、

>>> xmas_regex = re.compile(r'\d+\s\w+')
>>> xmas_regex.findall('12 drummers, 11 pipers, 10 lords, 9 ladies, 8 mailds, 7 swans, 6 geese, 5 rings, 4 birds, 3 hens, 2 doves, 1 partridge')
['12 drummers', '11 pipers', '10 lords', '9 ladies', '8 mailds', '7 swans', '6 geese', '5 rings', '4 birds', '3 hens', '2 doves', '1 partridge']

正規表現の「\d+\s\w+」は、1つ以上の数字(\d+)の次に、空白文字が1つ(\s)あり、1つ以上の文字/数字/下線(\w+)が続く文字列にマッチする

独自の文字集合

短縮形では、文字の集合が広すぎる場合は角かっこを使って独自の文字集合を定義できます。

[aiueoAIUEO]

てな感じで書いてコードとして実行するとそれだけ取り出せる

>>> vowel_regex = re.compile(r'[aeiouAEIOU]')
>>> vowel_regex.findall('RoboCop eats baby food. BABY FOOD.')
['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']

んで、

[^aiueoAIUEO]

とするとそれ以外にマッチすると記述できます。
※「^」はキャレット記号といいます。(はじめて知った

>>> consonant_regex = re.compile(r'[^aiueoAIUEO]')
>>> consonant_regex.findall('RoboCop eats baby food. BABY FOOD.')
['R', 'b', 'C', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']

キャレットとドル記号

キャレット(^)とドル($)はそれぞれ、

^ - 行の先頭
$ - 行の末尾

という意味があります。同時に使うと文字列全体が正規表現とマッチすることを示します。つまり、文字列の一部だけがマッチするだけでは不十分になります。

>>> begins_with_hello = re.compile(r'^Hello')
>>> begins_with_hello.search('Hello world!')
<re.Match object; span=(0, 5), match='Hello'>
>>> begins_with_hello.search('He said Hello.') == None
True

ここで25min。おしまい。思ったよりも25分って長いんだね。

この記事が気に入ったらサポートをしてみませんか?