2013年8月22日木曜日

正規表現でパスワード入力チェック

大阪のUです。
正規表現ってみんなどれぐらい使ってるんでしょう?

自分は正直あまり使ってません。。

使えば便利なのは判ってますが、
考えるのが面倒臭かったりするので、
プログラムで逃げたりして、なかなか使わない。。

たまに使う機会があっても、普段使ってないので、
すぐ忘れてしまう始末。

というわけで、プログラムで逃げてばっかりもアレなので
今回はちょっとパスワードの入力チェックを
正規表現でやる方法を考えてみました。

【条件】
・6文字以上であること。
・使用できる文字は半角数字、半角英小文字、半角英大文字、ハイフンのみであること。
・数字、英小文字、英大文字の混在であること。

【正規表現】
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z\-]{6,}$


いきなり答えを書いてますが、
自分はこれの元になった正規表現を見つけたとき、
何が書いてあるか判りませんでした。

[a-z]とかは普通によく使う表現ですが、
(?=.*[a-z])となると意味不明です。


というわけで順番に調べました。

^ ・・・・・・文字列の先頭
$ ・・・・・・文字列の末尾(改行文字除く)
. ・・・・・・改行文字(\n)以外の任意の一文字(カギ括弧内除く)
* ・・・・・・直前の文字を0回以上繰り返し。({0,}と同じ)

{n} ・・・・・直前の文字をn回繰り返し
{n,}・・・・・直前の文字をn回以上繰返し

[0-9] ・・・・0~9のいずれか1文字が含まれてること。
[a-z] ・・・・a~zのいずれか1文字が含まれてること。
[A-Z] ・・・・A~Zのいずれか1文字が含まれてること。
[\-] ・・・・ハイフンが含まれてること。(※\マークは任意だがあった方が判りやすい)

ここまでは基本中の基本って感じでしょうか。
で、上記を組み合わせて↓みたいにして使うと。

[0-9a-zA-Z\-] ・・・・・0~9、a~z、A~Z、ハイフンのいずれか1文字が含まれてること。
^[0-9a-zA-Z\-]$ ・・・・0~9、a~z、A~Z、ハイフンのいずれか1文字。
^[0-9a-zA-Z\-]{3}$・・・0~9、a~z、A~Z、ハイフンのいずれかで構成された3文字。

で、問題はこいつ。

(?= )

「ゼロ幅の肯定的先読みアサーション」というらしいですが
言葉だけだと意味不明です。

色々用例を調べた感じからすると、

直後に書かれた内容が、カッコ内に記述したパターンを満たしている事を
チェックする表現らしい。


(?=[a-z])

と書いた場合はa~zのいずれか1文字。つまり、

^(?=[a-z])[0-9a-zA-Z\-]{3}$

と書くと、直後の1文字目だけは、
(?=[a-z])の条件を満たしている必要があり、a~z以外の文字は×となる。

例)
×1aA
○aA1

この例だと1文字目だけが条件の対象だが、
以下のように書き換えると全体に対して有効になる。

^(?=.*[a-z])[0-9a-zA-Z\-]{3}$


(?=.*[a-z])は
任意の文字が0文字以上繰り返された後にa~zのいずれか1文字、
つまり文字列のどっかにa~zのいずれかがあることを意味するので、

”a~zのいずれかを含む”、0~9、a~z、A~Z、ハイフンのいずれかで構成された3文字となる。

例)
○1aA
×12A

そして、これを応用すると、
最初の答えにたどり着く。

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z\-]{6,}$"

”0~9のいずれかを含む”かつ
”a~zのいずれかを含む”かつ
”A~Zのいずれかを含む”、
0~9、a~z、A~Z、ハイフンのいずれかで構成された6文字以上の文字列。


う~む、今まで簡単な正規表現しか使ってなかったですが、
一行でここまで出来るとは。
まだまだ色々記述方法があるようだし、なかなか奥が深いです。


ただ、問題はみんなが理解してないと、
あとから見た人が判らない事ですかね・・・
プログラムと違って、なんとなくじゃ読めないし。