【正規表現】4種類の文字種のうち3種類を含む的なパスワードの正規表現

2021年6月6日

たまたまパスワードの正規表現を扱う機会があったので、備忘録として残しておくことにしました。

ちなみに正規表現の各記載の細かい説明はこの記事ではしません。

前提

こちらの正規表現はJava・Kotlin・Javascript等で動作するものです。一部言語では多少記載が変わる可能性があります。

以下正規表現チェッカーを使用して動作することを確認しています。

https://weblabo.oscasierra.net/tools/regex/

4種類の文字種のうち3種類を含む的なパスワードの正規表現

私が扱ったパスワードのポリシーは以下のようでした。

  • 英大文字・英小文字・数字・記号の4種類の文字種のうち3種類を含む
  • 使用可能な文字列は英大文字・英小文字・数字・パスワードの4種類
  • 8文字以上の文字数
  • 記号として使うのは「!@;:」(実際はもう少しあったのですが、長くなるので省略しました)

できあがった正規表現はこのようになりました。

^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@;:])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@;:])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@;:]))([a-zA-Z0-9!@;:]){8,}$

ちょっとだけ分解

いきなりこれを見てもわからないと思うので少し分解して全体的な説明だけしようと思います。

英大文字・英小文字・数字・パスワードの4種類の文字種のうち3種類を含む

こちらを表現している部分は以下です。

((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@;:])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@;:])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@;:]))

これを見てもまだ分かりづらいですが、 | で区切った箇所ごとだと読めると思います。それぞれを分解すると以下のようになっています。

  • (?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]) ⇒ 英小文字・英大文字・数字を含む
  • (?=.*[a-z])(?=.*[A-Z])(?=.*[!@;:]) ⇒ 英小文字・英大文字・記号を含む
  • (?=.*[A-Z])(?=.*[0-9])(?=.*[!@;:]) ⇒ 英大文字・数字・記号を含む
  • (?=.*[a-z])(?=.*[0-9])(?=.*[!@;:]) ⇒ 英小文字・数字・記号を含む

| で区切るとorになります。なので、文字種3種の組み合わせを4パターン記載しているだけです。

とっても簡単です。

使用可能な文字列は英大文字・英小文字・数字・パスワードの4種類

上のこの表現の場合は文字種3種を含んでいるとその他の文字がなんでも通るようになってしまう(例えば「1234aBC<>」みたいなものも通ってしまう)ので、以下を付与して使用できる文字列を定義しています。

([a-zA-Z0-9!@;:])

8文字以上の文字数

最後に以下をつけて8文字以上であることを定義しています。

 {8,} 

上限文字数が存在する場合は{8,30}のような感じで定義すると上限文字数を定義することができます。

参考