正規表現とは、文字列の一部分を抽出・置換したり、文字列が制約を満たしているかを調べるための表現方法です。
正規表現のメソッド
subメソッド
irb(main):001:0> str = "りんごを食べる"
=> "りんごを食べる"
irb(main):002:0> str.sub(/りんご/,"みかん")
=> "みかんを食べる"
文字列の指定した部分を別の文字列に置き換えるためのメソッドです。
第1引数に置き換えたい文字列、第2引数に変換後の文字列を指定します。
なお操作したい文字列は/
で囲みます。
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
引数に指定した文字列が、メソッドを使用した文字列に含まれているか否かをチェックするためのメソッドです。
含まれていない場合は、戻り値としてnilが得られます。
gsubメソッド
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"
g
はグローバルマッチの略で、文字列内に指定した文字が複数含まれている場合、
その全てを置換するという意味になります。
パスワードに英数字8文字以上の制約を設定する
「大文字小文字は両方可能で、英字もしくは数字8文字以上であること」
を条件とした場合、
英数字8文字でOKなパターン
irb(main):001:0> pass = 'Hoge1234'
=> "Hoge1234"
irb(main):002:0> pass.match(/[a-z\d]{8,}/i)
=> #<MatchData "Hoge1234">
英数字8文字以上に合致しているため、入力内容が返ってきます。
英数字7文字でNGなパターン
irb(main):001:0> pass = 'Hoge123'
=> "Hoge123"
irb(main):002:0> pass.match(/[a-z\d]{8,}/i)
=> nil
こちらは結果がnilとなり、8文字以上の英数字でないとmatchしないことを確かめることができました。
このように「結果がnilであればWebサイトのパスワードとして認めないようにする」とすることで、パスワード設定に制約を設けることが可能です。
「/[ a - z \ d ]{ 8 , }/ i」を噛み砕いて解説する
[a-z]
のポイント
①角括弧[ ]
を使用することで、囲まれた文字のうちいずれか1つがマッチするかをチェックしている。
②-(ハイフン)
を使用することで範囲を設定できる。
③[a-z]
はアルファベットのaからzまでのいずれかにマッチという意味になる。
a~cの英字を抽出【例】
irb(main):001:0> 'dog'.match(/[a-c]/)
=> nil
この場合「dog」に「a~c」は含まれないため、結果はnilとなる。
\d
のポイント
①このd
は特殊文字といい、数字を表している。=1や5といった数字が当てはまる。
②特殊文字を使用する場合は直前に\
を記述するというルールが存在する。
③今回は\d
は角括弧の内部にあるので、[a-z\d]は英数字のいずれか1つにマッチという意味になる。
数字のみ抽出する【例】
irb(main):001:0> 'I have 3 pens'.match(/\d/)
=> #<MatchData "3">
{n, m}
のポイント
①直前の文字が少なくとも n 回、多くても m 回出現するものにマッチすることを確認する。
つまり文字数の制約を追加することができる。
②{8, }
は、直前の文字が少なくとも8回出現するものにマッチという意味になる。
今回、波括弧の直前は[a-z\d]
であったため、英数字のいずれか1つが少なくとも8回出現するものにマッチという制約を持つ。
少なくとも4回、多くても6回出現するものにマッチ【例】
irb(main):001:0> '12345678'.match(/\d{4,6}/)
=> #<MatchData "123456">
irb(main):002:0> '123'.match(/\d{4,6}/)
=> nil
i
のポイント
①最後にiオプション
を加えることで大文字・小文字を区別せずに検索できる。
②iオプション
を付けない場合、[a-z]と小文字で記述しているため大文字にマッチしなくなる。
③反対に小文字のみという制約にしたい場合は、iオプション
を付けなければ良い。
大文字・小文字の区別【例】
irb(main):003:0> 'Cat'.match(/cat/)
=> nil
irb(main):004:0> 'Cat'.match(/cat/i)
=> #<MatchData "Cat">
メールアドレスからドメインの部分のみ抽出する
「hoge@gmail.com」というアドレスから「@gmail.com」の部分のみを取得したい場合、matchメソッドを使用することで抽出することができます。
irb(main):001:0> mail = 'hoge@gmail.com'
=> "hoge@gmail.com"
irb(main):002:0> mail.match(/@.+/)
=> #<MatchData "@gmail.com">
** .
のポイント**
ハイフンやピリオドなど含め、全ての英数字においてどの1文字にもマッチする。
irb(main):001:0> 'hoge'.match(/./)
=> #<MatchData "h">
+
のポイント
直前の文字が1回以上の繰り返しにマッチする。
irb(main):001:0> 'aaabb'.match(/a+/)
=> #<MatchData "aaa">
上記を踏まえると、.+
は何かしらの文字が1回以上繰り返すものにマッチする。
今回は/@.+/
として先頭に@を付けることで、「@から始まり、何かしらの文字が1回以上繰り返すものにマッチ」という意味になり、メールアドレスからドメイン部分のみを抽出することができた。
これにより「@ ~
という文字列ではない場合、メールアドレスの登録は認めない」という処理にも応用できる。
以上で正規表現の基礎知識編は終了です! ご指摘などあれば、ご教授いただけると幸いです。
次回は自分がオリジナルアプリに使用した正規表現まとめを投稿したいと思います。