蛇使いな彼女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)はちょっとややこしいので次回に持ち越しますね(;´∀`)
ではでは!