環境システム株式会社公式HP

〒660-0083 兵庫県尼崎市道意町7-1-3
尼崎リサーチ・インキュベーションセンター512

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

蛇使いな彼女BLOG

【第29回】 小技編③―Python正規表現(re)の使い方について #1.

2021.02.19

こんにちは!今回はこの正規表現を使った処理をやってみたいと思います。
……というのも、文字列パターンの探索は水質生データを解析する際に結構使えそうなツールで、臨機応変な動作をしてくれるからです(^u^)!

ただ、実は私も全容は分かっていないので、分かる範囲で書いていこうと思います!


★今日の例題プログラム★

同じ表記がたくさんあって分かりづらいので(番号)点線で区画を分けました。

(1)はパターンにマッチする文字列の探索(re.search)
(2)はパターンにマッチする箇所での分割処理(re.split)
(3)は水質データでよくあるエラー行(pattern3)を例に挙げた処理


いずれも正規表現を使った方法です(^_^)
正規表現を使った文字列の探索や抽出を行う際はreモジュールをインポートします。

本題の前に正規表現パターンに使われる記号の意味を一部、下の表に示しています。

正規表現パターン(記号) 意味
 . 改行以外の文字
\d 0~9までの数値。十進数。
{m} 直前のパターンをm回繰り返し。
先頭、先頭を含む。
直前のパターンを1回以上繰り返し
パターン(?=パターン) パターンパターンが続く
\Ⅾ dの打ち消し、0~9の数値以外。
\w 文字列、数値、アンダースコア。
$ 末尾、末尾を含む。
[集合] 集合内の文字
[^集合] 集合内の文字以外
\s スペース。空白文字。
パターン|パターン または。どちらかに一致すれば。
* 直前のパターンを0回以上繰り返し。
(パターン) パターンで1グループ。キャプチャ。

では(1)から順に解説と解答を見ていきます。


(1)解説 ◆



pattern='20201001000.csv'

#0~9の数値が4回繰り返されているパターン
re.search( '\d{4}',pattern).group()
#先頭を含む0~9の数値が1回以上繰り返されているパターン
re.search('^\d+',pattern).group()
#数値が3回繰り返されたパターンのあとに数値以外のパターンが続く
re.search('\d{3}(?=\D)',pattern).group()
#アルファベット全て、数字、アンダーバー(_)にマッチするパターンが1回以上続く,/
re.search('\w+',pattern).group()
#数値を3回繰り返し、数値以外のパターンを1回以上繰り返すパターン(末尾を含む)
re.search('\d{3}\D+$',pattern).group()



(1)では、re.searchを使って様々なパターンの探索を行っています。
re.search(正規表現パターン,対象)はオブジェクトを返すので、結果を確認するためにはgroup()メソッドを使います。
赤文字部分が正規表現となっています。
コードの説明はコメントに書いてあるとおりなので、記号の意味はさっきの表を参考にしてください。



(1)結果★ ※出力結果で表しています。



pattern='20201001000.csv'

#0~9の数値が4回繰り返されているパターン
re.search('\d{4}',pattern).group()
'2020'

#先頭を含む0~9の数値が1回以上繰り返されているパターン
re.search('^\d+',pattern).group()
'20201001000'

#数値が3回繰り返されたパターンのあとに数値以外のパターンが続く
パターン(?=パターン)
re.search('\d{3}(?=\D)',pattern).group
'000'

#アルファベット全て、数字、アンダーバー(_)にマッチするパターンが1回以上続く
re.search('\w+',pattern).group()
'20201001000'

#数値を3回繰り返し、数値以外のパターンを1回以上繰り返すパターン(末尾を含む)
re.search('\d{3}\D+$',pattern).group()
'000.csv'



こんな感じですがどうでしょう?
re.searchは、文字列全体に対し、正規表現パターンに一致した最初の文字列を1つ返すようです。

ところで、\w+\d+の結果が同じになっていますよね。

\dは10進数数字に一致するのに対して、\wは文字、数字、アンダーバー( _ )に一致します。
ですが、ここでの文字というのは「.」や「,」は含まないアルファベットのAからZまでなので、結果は'20201001000'となってしまいます。

「.csv」部分を探索したい場合はすこしパターンを変えて、'\w+$'とすれば '.csv'となります。
「.csv」も\w+のパターンに当てはまります。
が、「20201001000」以降の2つ目のパターンなので、re.searchではヒットしません。
パターンに一致する全ての文字列を参照する場合は、re.findallを使います。(これは次回(3)で説明します)



(2)解説 ◆



pattern2='2020-10-01 000.csv'
#0~9の数値以外のパターンが1回以上繰り返すパターンで分割
re.split('\D+', pattern2)


re.splitを使った分割を行います。re.searchと違い、メソッドなしで結果を返してくれます。

(2)結果★



結果は、['2020', '10', '01', '000', '']と指定したパターンで分割したリストが返ってきます。簡単ですね(^_^)
それにしても、結果の最後は‘’となってしまうということは…「.csv」を1グループとして分割したけど、それに続く文字列がなかったからでしょうか?これも1つの発見ですね(・o・)

さて、一度に説明すると長いので今日は一旦ここまでにします!
(3)はちょっとややこしいので次回に持ち越しますね(;´∀`)

ではでは!

pagetop