アウトプットを頑張る

初めてのプログラミング学習期間中の記録と、日頃読んでいる本をメモのアウトプットをがんばります。

【プログラミング学習】正規表現とは Part2

■プログラミング学習 f:id:yuma6128:20211204074659j:plain

応用的な使用方法のパターン

  • 電話番号のハイフンを取り除く
  • パスワードに英数字8文字以上という制約を設定する
  • メールアドレスからドメイン部分のみを抽出する


電話番号のハイフンを取り除く
特定の文字を取り除く場合は、「特定の文字を空文字に置換する」と考えます。
置換するメソッドは前回紹介したsubメソッドになります。
しかし、subメソッドでは最初の文字しか置換されないため
gsubメソッドを使用します。
gが意味するのはグローバルマッチという言葉です。
文字列内に指定した文字が複数含まれている場合、その全てを置換するという意味になります。
gsubではなく、subを使用した場合、最初にマッチした1つだけが置換されます。

[1] pry(main)> tel = '090-1234-5678'
=> "090-1234-5678"

[2] pry(main)> tel.sub(/-/,'')
=> "0901234-5678"
# 最初の-しか置換されていない

[3] pry(main)> tel.gsub(/-/,'')
=> "09012345678"

パスワードに英数字8文字以上という制約を設定する
今回のパスワードの条件は「大文字小文字両方可能で、英字もしくは数字8文字以上であること」にします。
設定するパスワードは「Test1234」とします。
matchメソッドを使用して、下記のように記述します。

[1] pry(main)> pass = 'Test1234'
=> "Test1234"
[2] pry(main)> pass.match(/[a-z\d]{8,}/i)
=> #<MatchData "Test1234">

パスワードを1文字減らして、7文字にした場合はどうなるか。

[4] pry(main)> pass = 'Test123'
=> "Test123"
[5] pry(main)> pass.match(/[a-z]\d]{8,}/i)
(pry):5: warning: regular expression has ']' without escape: /[a-z]\d]{8,}/
=> nil

結果はnilになっているため、8文字以上の英数字でないとmatchしないことが確認できました。
よくある処理としては、この結果がnilであればWebサイトのパスワードとして認めないようにする、といったものが例として挙げられます。
下記表現について、解説をいたします。

  • [a-z]
  • \d
  • {n,m}
  • i

    [a-z]
    角括弧[]を使用することで、囲まれた文字のうちいずれか1つがマッチするかをチェックしています。
    -(ハイフン)を使用することで、範囲を設定することができます。
    つまり、[a-z]はa~zまでいずれかにマッチ、[a-d]はa~dまでいずれかにマッチという意味です。

    \d
    このdは数字を表しています。このdのような文字を特殊文字と呼びます。
    特殊文字を使用する際には、直前に\を記述するルールがあります。
    今回の/[a-z\d]の場合は、\dが角括弧の内側にあるため、英数字のいずれか1つにマッチという意味になります。

    {n,m}
    直前の文字が少なくとも「n」回、多くてもm回出現するものにマッチすることを確認します。
    こちらで、文字数の制約を追加しています。

    i
    最後にiオプションを加えることで、大文字・小文字を区別せずに検索します。
    iオプションをつけない場合、[a-z]と小文字で記述しているため大文字にマッチしなくなってしまいます。
    小文字のみに制約をするという場合は、iオプションをつけないことで対応可能です。

    メールアドレスからドメイン部分のみ抽出する
    matchメソッドを使用することで、抽出することができます。
[1] pry(main)> mail = 'test_sample@mail.com'
=> "test_sample@mail.com"

[2] pry(main)> mail.match(/@.+/)
=> #<MatchData "@mail.com">

「.」はハイフンやピリオドなどを含めたすべての英数字において、どの1文字にもマッチします。

[4] pry(main)> 'test'.match(/./)
=> #<MatchData "t">
[5] pry(main)> 'abcd1234'.match(/./)
=> #<MatchData "a">

「+」は直前の文字が1回以上繰り返すものにマッチします。

pry(main)> 'aaaabcd1233'.match(/a+/)
=> #<MatchData "aaaa">

上記二つを組み合わせて「.+」とすることで、何かしらの文字が1回以上繰り返すものにマッチします。
先頭に@をつけることで@から始まり、何かしらの文字が1回以上繰り返すものにマッチするという意味になります。
こうすることで、メールアドレスからドメイン部分のみを抽出することが可能で、もしも「@~」という文字列でなかった場合に、メールアドレスとして登録を認めないという処理に応用できます。