LoginSignup
48
66

More than 1 year has passed since last update.

【誰でもわかる正規表現!】 やってみたら超簡単だった

Posted at

はじめに

 みなさん、正規表現が便利なのは知っていますか?

Qiitaをご覧になっている方であれば、多くの人が YES と答えているでしょう。
では、正規表現使ってますか?
今度は、... という微妙なところでしょうか。

 それもそのはずで、正規表現は理解のとっかかりが掴みづらい。
見慣れない記号が並んでいて、意味を把握するのが難しい。
その上、解説しているサイトも難解なものが多い。
(平易に説明しているものが少ない。)

 このような状況の中で正規表現を使いこなせるようになるには、
...ズバリ 「用途を限定する」 ことでしょうか。

特定の用途なら割と簡単なものがあるので、1個でも組めれば、
それをきっかけにしてレパートリーが増えていくものかと。
そしていつの間にか、全体像を自然に把握しているようになります。

早い話がボトムアップ式で覚えていくのがベター!!

と、いうわけでこの記事では「正規表現で整数(半角)にマッチさせる」
ことを紹介したいと思います。

 とりあえずこの用途だけなら簡単にマスター可能でしょう。

対象となる読者

 とりあえず、正規表現を使ってみたい人を対象としています。

  • 簡単に説明してほしい
  • 初心者で正規表現の予備知識が無い人
  • 何らかのプログラミング言語を使っているが、正規表現は避けている
  • テキスト処理で整数について処理したい
  • オライリーの本は読む気がしない

こういった方に向けて説明します。

参考にしたサイト

 割と分かりやすく解説しているもの。

サルにもわかる正規表現入門
ゆびノート
みやびのどっとぴーわい

動作環境

 Python3系でいきましょう。
それでは以下から本編です。

やりたい事

 整数(半角)にマッチさせる。
但し以下の条件を満たすのもとする。

条件その1:

     0~59までの範囲の数字

条件その2:

     1桁の場合はゼロ埋めしない(02などは除外する)

メタキャラクタ

 正規表現では「メタキャラクタ」という記号を用いる事で整数を表現できる。
\d[0-9] などである。
しかし \d はPythonだと半角整数だけでなく、全角数字など余計なもの(ゆびノートさんによればジャワ数字もヒットしている)も含まれる。

 そこで、\d ではなく [ ] のほうを使う。
この記号は [ ] の中に指定した文字のどれかにヒットする。
0 から 9 までの数字を指定したい場合には [0123456789] でも可能だが、サルにもわかる正規表現入門さんによると、面倒なので[0-9]でも大丈夫とのこと。

 これで整数の表し方がわかったので、2桁の整数なら[0-9]を2つ並べて[0-9][0-9]とすればよさそうだ。
だがこれだと、整数が1桁の場合0埋め(03など)されてしまう。

... これに対処するには 1桁の場合と2桁の場合で別々に処理する。

1桁の場合

 条件は0~59までの数字なので、1桁のときは 0~9 までの数字を使う。
つまり、[0-9] でOKだ。

2桁の場合

 2桁の数字で条件を満たすものは 10~59 だ。
そうすると2桁目は、[1-5] で1桁目は [0-9] である。
二つ並べて[1-5][0-9]とする。

 後は1桁の場合か2桁の場合かの、どちらかを表すメタキャラクタである | を使う。

[0-9]|[1-5][0-9]

これで完成と言いたいところだが、まだ問題が残っている。
それは、「数字の区切り」である。

区切り文字

 例えば 15 の場合なら2桁の数字としてマッチさせたい。
しかし残酷にもこれは 15 のうち 1 の部分が1桁の場合である[0-9]のほう( | の左側)にマッチしてしまう。
 これを回避するには、区切りを示すメタキャラクタである\bも付け加える。

\b[0-9]\b|\b[1-5][0-9]\b
これで 15 のような場合は2桁の数字としてマッチさせることが出来るようになる。

ようやく正規表現が完成したので次は、Pythonで実装してみる。

Python!

対話型より
#pythonから正規表現を使うには re をインポートする
>>> import  re
#作成した正規表現を compile() の引数に渡す
>>> pat = re.compile(r"\b[0-9]\b|\b[1-5][0-9]\b")
#判定対象の文字列
>>> score = "15 54 9 60 123 03 30"
#findall()はマッチがあるとリストを返す。(マッチしたもの全て)
>>> pat.findall(score)
['15', '54', '9', '30']

まとめ

この記事では、次のような事を理解しました。

  • 正規表現ではメタ文字を使う。
  • メタ文字の [0-9] で整数を表せる。
  • A|B は AかBかを示す。
  • \b で区切りをつける。

 今回は「整数」の取り扱いに的を絞りました。
簡単なものから実際に手を動かしてみる事で、徐々に理解が深まるのが実感できると思います。
正規表現はこの他にも多くの種類がありますが、本記事を契機としてレパートリーを増やしていきましょう!

 なお、この記事を読んで簡単だと感じた頭がいい人は是非とも、オライリーの本や難解なサイトにも挑戦して下さい。

今回はこの辺で。

48
66
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
48
66