はじめに
私の過去の記事で,ユーザ管理機能の実装でdeviseをご紹介しました。その際に特別触れることはありませんでしたが、実はdeviseではemailのアドレス登録で@をつけることが必須です。
当時は、便利だな〜と思いましたがその仕組みが気になり、調べていくと、、、
「正規表現」といものと巡り合ったのでこの記事にてご紹介します。
正規表現とは
正規表現とは、文字列の一部を抽出あるいは置換をしたり、文字列が制約を満たしているかを調べるための表現方法です。
たとえば、あるアンケートで電話番号と郵便番号を書かせるフォームがあったとします。
その時にただの空欄ボックスであった場合にハイフンをつけたりつけなかったり、いろんな人がでてきて管理がしづらいですよね。なので、正規表現によってハイフンが入っていたら取り除いたりするわけです。
このように文字列に特定の文字が含まれているかを確認することや、特定の文字を取り除くなどの操作を行うための技術が正規表現です。
正規表現の基礎
まずは正規表現を利用するための3つのメソッドをご紹介します。
・subメソッド
・matchメソッド
・gsubメソッド
subメソッド
subメソッドは、文字列の指定した部分を別の文字列に置き換えるためのメソッドです。
操作する文字列は//で囲ってやって、第2引数に置換後の文字列を入れます
こんな感じです
irb(main):001:0> str = "ラーメンを食べる"
=> "ラーメンを食べる"
irb(main):002:0> str.sub(/ラーメン/,"チャーハン")
=> "テャーハンを食べる"
matchメソッド
matchメソッドは、指定した文字列がある文字列に含まれているか否かをチェックするためのメソッドです。
これはみた方が理解が早いので以下に例を示します。
irb(main):001:0> str = "Hello, World"
=> "Hello, World"
irb(main):002:0> str.match(/Hello/)
=> #<MatchData "Hello">
irb(main):003:0> str.match(/Good/)
=> nil
戻り値には、MatchDataという種類のオブジェクトで返されます。
gsubメソッド
指定の文字列すべてを置換します。
subと似ていますね。ただし、subの場合、最初にマッチした文字列に対してのみで、gsubは全てです。
そう、gとはgrobalのこと、全てなのです!!!!(笑)
irb(main):001:0> tel = '090-1234-5678'
=> "090-1234-5678"
irb(main):002:0> tel.sub(/-/,'')
=> "0901234-5678"
# 最初のハイフンしか置換されない
irb(main):003:0> tel.gsub(/-/,'')
=> "09012345678"
いよいよバリデーションの準備です!!
ここまでで、なんとなく基本的な部分は理解できましたか??
ここからはさっそくバリデーションをかける準備です。
今回はパスワードに4文字以上という制限をかけましょう。
先に結論から言うと、こんな感じにします。
validates :password,format:{with: /[a-z\d]{4,}/i }
初見殺しすぎますよね。。。わかります。。。。
でも焦らない!一つづつ見ていきましょう。
まず、/[a-z\d]{4,}/iの部分を分解してみましょう。
[a-z]
\d
{n, m}
i
[a-z]
角括弧[]を使用することで角括弧で囲まれた文字のうちいずれか1つがマッチするかをチェックしています。-(ハイフン)で範囲を設定することができます。
今回はアルファベットのaからzまでのいずれかにマッチという意味になります。
実際にmatchを使って見てみます
irb(main):001:0> 'debug'.match(/[a-c]/)
=> nil
\d
これは数字を表します。なお、このような文字を特殊文字といいます。
{n, m}
直前の文字が少なくとも n 回、多くても m 回出現するものにマッチすることを確認します。
i
iはオプションで、大文字・小文字を区別せずに検索します。
もう意味はわかりましたか??
ここまでこればもう意味はなんとなくわかってきたはず!!
もう一度さっきのバリデーションをみてみましょう
validates :password,format:{with: /\A[a-z\d]{4,}\z/i }
/[a-z\d]{4,}/i を読むと、
[a-z\d](英数字を)
{4,}(最低4回)
/i(大文字小文字区別なく)
と言う意味になります!!!
追記(2021年4月4日):
英数字4文字以上のパスワードにするためには、文字列の最初ですと言う意味を持つ\Aと文字列の末尾ですよと言う芋を持つ\zが必要です。詳しくはこちらをどうぞ。
https://qiita.com/itsumoonazicode/items/e3c7886909ce68986c9a
この制約でのフォーマットをバリデーションをかけると上記のようになるわけです。
おわりに
以上、正規表現についてざっくりですがご紹介いたしました、
ほかにもたくさん表現の仕方があるので興味のある方は調べてみてください!!