Python3メモ⑮(正規表現)

正規表現とは文字列をパターンで表現したものです。

主に以下の3つで使用します。
・パターンに適合している文字列があるかどうかを判定する
・パターンに適合している文字列があれば、それを別の文字列に置換する
・パターンに適合している文字列があれば、それを抜き出す

文字列メソッドでも、「あるかないか判定」や、「置換」はできますが、正規表現と何が違うのかと言いますと、文字列そのもので判断するのか、パターンで判断するのかの違いです。

文字列メソッドの復習

正規表現で行う

正規表現を使う場合、reモジュールをインポートします。
以下、よく使いそうなものだけ抜粋します。
詳しくはhttps://docs.python.jp/3/library/re.html参照。

search

マッチオブジェクト = re.search(パターン, 探す文字列[, flags=0])
文字列を走査し、パターンがマッチする最初の場所を探して、対応するマッチオブジェクトを返します。
文字列内にパターンにマッチする場所が無い場合は None を返します。
flagsはオプションですが、後述しますが、複数行でマッチさせる場合等の指定を書き加えられます。

結果
あります
ありません

この場合、パターンに通常の文字をそのまま入れて探していますので、正規表現を使う意味はあまりありません(文字列メソッドやin演算子でできます)。

結果
あります

変数mojiの中に「文..」という文字はないのにもかかわらず、「文..」が「あります」になりました。
まず、r”文..”のrですが、これは以前書きましたraw文字列で、正規表現のパターンを記述する時は書いた方が便利です。
そして「文..」のドット「.」ですが、これは任意の1文字という意味です。この「.」のような特殊文字が色々ありまして、通常の文字と特殊文字を組み合わせてパターンを書きます。

結果
表現とは、

表現という文字は2箇所出てきますが「表現..、」にマッチするのは「表現とは、」だけであり、マッチオブジェクトのgroupメソッドでマッチした文字列の取得をしています。

結果
文字列の集合を一つの文字列で表現する方法
文字列

#1で「(文.+)の」のパターンで、丸括弧は一つのグループで、group(1)で最初の丸括弧のグループを取得します。
「+」は前の文字の一回以上の繰り返しで、「文」で始まり、任意の文字の一回以上の繰り返しで、「の」までにマッチするものを探します。
#1と#2のパターンはほぼ同じですが、「(文.+?)の」の?だけが違います。この場合の?は最短マッチを意味します。
結果を見て、最短マッチされていることを確認して下さい。

findall

リスト = re.findall(パターン, 探す文字列[, flags=0])
searchは複数マッチしても最初の部分しか返しません。複数のマッチを取得するにはfindallを使います。
以下、Yahoo!ニュースのrssから記事のタイトルとリンクをfindallで抜き出してみます。

結果
酒で外国語うまく 実験で確認
https://news.yahoo.co.jp/pickup/6258538
「若いダイヤ」発見 業界騒然
https://news.yahoo.co.jp/pickup/6258531
炭水化物抜き 潜む落とし穴
https://news.yahoo.co.jp/pickup/6258484
腸で口内細菌増えると潰瘍に?
https://news.yahoo.co.jp/pickup/6258314
10月なのに超大型台風 なぜ
https://news.yahoo.co.jp/pickup/6258248
台風観測「目」に計器を投下
https://news.yahoo.co.jp/pickup/6258186
白亜紀のカエル 恐竜を捕食か
https://news.yahoo.co.jp/pickup/6258276
若者にもスマホ老眼 防ぐには
https://news.yahoo.co.jp/pickup/6258196

パターンが長くなってきましたので、pattern変数に入れています。
itemタグ内でtitleとlinkを抜き出します。「(.*?)」*は0回以上の繰り返しです。
findallの戻り値はリスト型になりますが、丸括弧グループが2つ以上ある場合は、リストの要素はタプルになります。
このように返ってきます。
[
(‘酒で外国語うまく 実験で確認’, ‘https://news.yahoo.co.jp/pickup/6258538’),
(‘「若いダイヤ」発見 業界騒然’, ‘https://news.yahoo.co.jp/pickup/6258531’),



]
flags=(re.MULTILINE | re.DOTALL)は、MULTILINEは複数行対応、DOTALLは特殊文字「.」を、改行を含むどんな文字にもマッチさせるということです。

sub

正規表現で文字列を置換する場合はsubを使います。
置換後の文字列 = re.sub(パターン, 置換する文字列, 置換される文字列[, count=0][, flags=0])
count は、置換される回数、もし省略されるかゼロであればすべて置換。
flagsは前と同じ。
パターンに該当しない場合は、元の文字列がそのまま返ります。

結果
正規表現とは、モジレツの集合を一つのモジレツで表現する方法の一つである。

パターンでグループ化した正規表現が、第二引数の内部で\1や\2などのような特殊文字で「後方参照」することが出来ます。

結果
正規表現は文字列の一つである。

第一引数で丸括弧を3つグループ化しています。それぞれを第二引数内の\1、\2、\3で参照しています。
「(.{6})$」これは、任意の文字6文字が末尾にマッチ($)するものということです。

正規表現のパターンの書き方は一朝一夕には覚えられません。
しかし、正規表現のパターンの書き方はPythonだけではなくて、色々なプログラミング言語でほぼ共通なので、覚えておくと便利です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする