よくある正規表現のまとめとPHP,JSでの入力値のバリデーション

# バリデーションとは
バリデーションとかメモしておくと後々楽そうなので実装方法をメモ。

>「バリデーション」とは、「検証、実証、認可、妥当性」を意味する英単語になります。
>例えば、「文書をバリデーション」といった場合には、「記述・入力されたデータが、
>あらかじめ規定された条件・使用に適合しているか検証・確認する。」ことを表します。
 [引用元](https://career-picks.com/business-yougo/validation/)


つまり、入力された値に対して、
事前に決められた形式（英数字のみなど）に沿っているかを判定し、
沿っていない場合はエラーを返すような機能を指します。


## 実装方法の概要
1. 正規表現で正常な形式であればマッチするよう記載する
2. マッチしなかった場合はエラーを返す

で実装します。

## そもそも正規表現って
### 正規表現の種類について
この手の検索をしていると、
サイトによってどういった書き方をするかがバラバラである。
それは正規表現の書き方が複数あることにも要因がある。
具体的には以下のような種類がある。

 [正規表現](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions)
>**言明**
>何らかの方法でマッチが可能なことを示します。言明は先読み、後読み、条件式を含みます。
>x(?=y)など
>
>**境界**
>行や文字の始まり・終わりを示します。
>$や^など
>
>**文字クラス**
>文字や数字の区別など、文字の種類を区別します。
>\dや\sなど
>
>**グループと範囲**
>式にある文字のグループと範囲を示します。
>x|yや[a-c]など
>
>**数量詞**
>マッチする文字や式の数を示します。
>{n,m}や*など
>
>**Unicode プロパティエスケープ**
>大文字と小文字、数学記号、句読点など、Unicode文字のプロパティに基づき区別します。
>下記にある\p{Han}など

ひとつの正規表現内にこれらの表現を織り交ぜつつ利用するのが普通なため、
ものによっては複数の書き方が可能である


### 代表的な正規表現
正規表現の種類を大前提とし、よくあるパターンをピックアップ。
なお、一般的な正規表現は [正規表現一覧](http://gimite.net/help/devas-ja/all_regex.html)を確認する。

| 正規表現 | 意味 | 
|:-----------------:|:------------------:|
| [a-zA-Z] | アルファベット |
| [0-9] | 数字 | 0000-0FFF |
| [ぁ-ん] | ひらがな |
| [ァ-ヴ] | カタカナ |
| [\p{Han}] | 漢字 |
| 後述 | メールアドレス |

-で範囲していとなる正規表現だが、
一部は注意して扱わないと余計な文字が入ってしまう。
ネットなどからコピペして使用する場合も必ず以下の文字コード一覧を参照すること。
 [文字コード一覧](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF)

例えばアルファベットについては、
[a-Z]で指定可能という記事なども見かけるが、
それでは[\]^_`といった余計な文字も含まれてしまうことが上記からわかる。


メールアドレスについては、
99.9%が合致すると謳っている以下のサイトを参考にする。
 [emailregex](http://emailregex.com/)

## PHPでの正規表現マッチとバリデーションpreg_match
基本的にはpreg_matchを使用する。

preg_matchでは3つ目の引数にマッチした値が配列で格納される。
 [PHPリファレンス](https://www.php.net/manual/ja/function.preg-match.php)
>\$matches[0] にはパターン全体にマッチしたテキストが代入され、
>$matches[1] には 1 番目のキャプチャ用サブパターンにマッチした 文字列が代入される。
>サブパターンは()で囲うことで実現できる。

なお、正規表現であることを表現するためには、
正規表現の前後を/（バックスラッシュ）で囲う必要がある。

```php
<?php
preg_match('/(foo)(bar)(baz)/', 'foobarbaz', $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>
```

```php
Array
(
    [0] => Array
        (
            [0] => foobarbaz
            [1] => 0
        )

    [1] => Array
        (
            [0] => foo
            [1] => 0
        )

    [2] => Array
        (
            [0] => bar
            [1] => 3
        )

    [3] => Array
        (
            [0] => baz
            [1] => 6
        )

)
```

例えば、正規表現にマッチした入力の場合、
Logに出力するような処理であれば以下のようになる。

```php
$orgName = 判定する文字列を挿入
if(preg_match('/正規表現/', $orgName, $matches)){
    \Log::warning("ファイル名は半角英数字で指定してください。| $orgName");
}
```

## JSでの正規表現マッチとバリデーションpreg_match
execメソッドかtestメソッドを使用します。

| メソッド名 | 説明 |
|:-----------------:|:------------------:|
| exec | 文字列中で一致するものを検索する RegExp のメソッドです。結果情報の配列を返します。 |
| test | 文字列中で一致するものがあるかをテストする RegExp のメソッドです。true または false を返します。 |

そのため、判定の結果判定文字列内の文言を使って処理をする場合はexec、
単純にエラーメールを飛ばすなどであればtestを使うこととなるかと思います。

exec()の使い方は

```js
var regex1 = /(fo)(o)*/;
var str1 = 'table football';
var array1;
array1 = regex1.exec(str1);
console.log(array1[0]);
// > "foo"
console.log(array1[1]);
// > "fo"
console.log(array1[2]);
// > "o"
```

exec() の配列はマッチ結果がなかった場合はNullを、
マッチ結果があった場合は配列[0]にマッチ文字列全体を、
配列[1]以降にサブパターンにマッチした 文字列が代入される。
サブパターンはPHP同様()で囲うことで実現できる。

パターンマッチした場合は、
erros配列に格納するといった場合は以下のように実装する。
```

```js
//　Viewで表示するためのエラー用配列
var errors = [] ;
mailPattern = 正規表現 ;
mailAddress = "aaa@example.com"

if(!mailPattern.test(mailAddress)){
    errors.push("メールアドレスを正しく入力してください。");
```

**参考**
---
 [正規表現を使うときに注意すべきこと](https://qiita.com/kokorinosoba/items/78811d7e2b6bc424b1b1)
 [正規表現がわからないときは文字コードがヒントになる](https://qiita.com/haruna-nagayoshi/items/dd6a7c43cdc55340292d)