【CakePHP】バリデーションメソッドをまとめた

#はじめに#
CakePHP(3.8)のバリデーションメソッドまとめです。
バリデーションの基本は、Validationクラスのインスタンスに、チェーンメソッドで適応したルールを記述していきます。

```php
use Cake\Validation\Validator;

$validator = new Validator();

$validator
    ->requirePresence('age')
    ->notEmpty('age', 'このフィールドに入力してください')
    ->nonNegativeInteger('age', '年齢は数字で入力してください。')
```

Validatorクラスは、基本的にはValidationクラスのラッパーになっています。(例外もあります)
そのため、実際にどのような処理が行われるかを知るためには、Validationクラスを覗く必要があります。

```Validator.php
public function nonNegativeInteger($field, $message = null, $when = null)
{
    $extra = array_filter(['on' => $when, 'message' => $message]);
    return $this->add($field, 'nonNegativeInteger', $extra + [
        'rule' => ['naturalNumber', true]
    ]);
}
```

##一覧##
| メソッド名 | 説明 |
|:-:|:-:|
| add  | ルールを追加する  |
| addNested |  ネストされたデータをバリデートする |
| addNestedMany  | 1対多の関係をバリデートする  |
| remove | ルールを削除する |
| requirePresence | フィールドに存在することを要求する。nullは許容する |
| allowEmpty | 空を許容する。3.7から非推奨|
| notEmpty |空を認めない。フィールドに存在することは要求しない。3.7から非推奨|
| notBlank |空を認めず、更に半角スペースも認めない|
| allowEmptyString | 空を許容し、かつ文字列か |
| notEmptyString | 空を認めず、かつ文字列か |
| allowEmptyArray | 空を許容し、かつ配列か |
| notEmptyArray| 空を認めず、かつ配列 |
| allowEmptyFile | 空を許容し、かつファイルか |
| notEmptyFile | 空を認めず、かつファイルか |
|allowEmptyDate | 空を許容し、かつ日付型か |
| notEmptyDate | 空を認めず、かつ日付型か |
|allowEmptyTime | 空を許容し、かつ時刻か |
| notEmptyTime | 空を認めず、かつ時刻か |
|allowEmptyDateTime | 空を許容し、かつdatetime型か |
| notEmptyDateTime | 空を認めず、かつdatetime型か |
| alphaNumeric | 半角英数字か |
| lengthBetween | 指定した文字数の範囲か|
| creditCard | クレジットカードの形式か|
| greaterThan | 指定した数字を超えるか | 
| greaterThanOrEqual | 指定した数字以上 |
| lessThan | 指定した数字未満 |
| lessThanOrEqual | 指定した数字以下 |
| equals | 指定した数字と一致 |
| notEquals | 指定した数字と不一致 |
| sameAs | 指定したフィールドと一致（厳格な比較) |
| notSameAs | 指定したフィールドと不一致(厳格な比較) |
| equalToField | 指定したフィールドと一致 |
| notEqualToField | 指定したフィールドと一致 |
| greaterThanToField | 指定したフォールドを超える |
| greaterThanOrEqualToField | 指定したフィールド以上 |
| lessThanToField | 指定したフィールド未満 |
| lessThanOrEqualToField | 指定したフィールド以下 |
| containsNonAlphaNumeric | 指定した回数英数字以外が含まれているか |
| date | ymd形式がどうか |
|datetime | datetime形式がどうか |
| time | 時刻の形式かどうか |
| boolean | 真偽値かどうか |
| decimal | 十進数小数か |
| email | メールアドレス形式か |
| ip | IPアドレスの形式か |
| ip4 | IPv4の形式か |
| ip6 | IPv6の形式か |
| minLength | スカラ値が指定した文字数以下か |
| maxLength | スカラ値が指定した文字数以下か |
| minLengthBytes | スカラ値が指定したバイト数以下か |
| maxLengthBytes | スカラ値が指定したバイト数以下か |
| numeric | is_numericか |
| naturalNumber | 自然数かどうか |
| nonNegativeInteger | 0以上の自然数か |
| range | 指定した範囲の数値か |
| url | urlの形式か |
| urlWithProtocol | urlの形式で、スキーマが必須 |
| inList | リストの中に存在するか |
| uuid | uuidか |
| uploadedFile | ファイルの形式か |
| latLong | 経度または緯度の形式か |
| latitude | 経度か |
| longitude | 緯度か |
| ascii | ASCII文字か |
| utf8 | BMP UTF-8文字か |
| utf8Extended | UTF-8文字か |
| integer | 数字か |
| isArray | 配列か |
| isScaler | スカラ値か |
| hexColor | 16進数カラーコードか |
| multipleOptions | 複数選択セレクトボックスの値か |
| hasAtLeast | フィールドが指定された数以上の要素をもつか |
| hasAtMost | フィールドが指定された数以下の要素をもつか |
| regex | フィールドが正規表現に一致するか |

#共通してる引数#
##`$field`##
バリデーションの対象となる配列の、バリデーションをかけたいフィールドをキーを渡します。
これは、配列で渡すことによって、複数のフィールドを同時にバリデーションを適応することが可能です。

##`$message = null`##
バリデーションが発動した際の、エラーメッセージを指定します。この引数が渡されなかった場合、デフォルトのエラーメッセージが出力されます。

##`$when = null`##
以下の3つから選択することができます。
- create 新規作成時にバリデーションを適応する
- update 更新時にバリデーションを適応する
- コールバック関数

3つ目のコールバック関数について、具体例を提示します。

```php
$validator->requirePresence('credit_card', function ($context) {
    if(isset($context['data']['payment']) {
        $context['data']['payment'] === 'credit';
    }
    return false;
});
```

コールバック関数の戻り値は、真偽値か、エラーメッセージを意味する文字列である必要があります。
`$context['data']`には、同時に送られた配列が入っています。
これは、支払い方法がクレジットカードの場合には、クレジットカード番号が必須項目となる例です。

#ルールに関するメソッド#
これらは、他のメソッドと異なり、ルールを追加するために使用されるメソッドです。

##add#
```php
$validtor->add($field, $name, $rule = [])
```

新しいルールを追加することができます。
以下のように既存のルールを追加することができますが、基本的にはラッパーから読んだほうが簡潔になります。

```php
// これらは同じルールが適応される。addを使用して追加した場合には、ルールの名前を決めることができる。
$validator->add('password', [
    'size' => [
        'rule' => ['lengthBetween', 8, 20],
        'message' => 'パスワードは8文字以上20文字以下にする必要があります。'
    ]
]);

$validator->lengthBetween('password', [8, 20], 'パスワードは8文字以上20文字以下にする必要があります。');
```

addが真価を発揮するのは、[自分で作ったルールを適応させられる](https://book.cakephp.org/3/ja/core-libraries/validation.html#custom-validation-rules)ところです。

##addNested##
```php
$validator->addNested($field, Validator $validator, $message = null, $when = null)
```

バリデーションインスタンスを与えて、バリデーションをネストすることができます。
とはいえ、エンティティをバリデーションする際には、アソシエーションするモデル側でバリデーションルールを記述すれば、通常ネストされている
バリデーションも適応されるので、これはモデルのないフォームに利用されます。

##addNestedMany##
```php
$validator->addNestedMany($field, Validator $validator, $message = null, $when = null)
```

1:多の関係をネストします。addNestedと同じく、モデルのないフォームに利用されます。

##remove##
```php
$validator->remove($field, $rule = null)
```

フィールドのルールを削除します。`$rule`には、ルール名を指定します。
`$rule`が指定されなかったときは、そのフィールドのすべてのルールが削除されます。


#通常のバリデーションメソッド#
##requirePresence##

```php
$Validator->requirePresence($field, $mode = true, $message = null)
```

バリデーションの対象となる配列のフィールドに対して、実在することを求めます。
具体的には、`array_key_exists`を用いてキーの存在を確かめるため、nullは許容されます。
そのため、notNull制約を実現したい場合には、`notEmpty`などと組み合わせて使うことが一般的です。

また、`$mode`を指定することによって、以下の5つのモードを選択することができます。デフォルトはtrueです。

- true 常にこのフィールドが存在することが求められる。
- false フィールドが存在する必要がなくなる。
- create 新規作成時にバリデーションを適応する
- update 更新時にバリデーションを適応する
- コールバック関数

一般的なバリデーションメソッドと引数の順番が違うのは、requirePrecenceはラッパーメソッドではないからです。

##allowEmpty##
```php
$validator->allowEmpty($filed, $when = null, $message = null)
```
空を許可します。これも、ラッパーメソッドではないので、引数の順序が異なります。
3.７からは、非推奨となり、代わりに以下のメソッドを使うことが推奨されています。

- `notEmptyString()`
- `notEmptyArray()`
- `notEmptyFile()`
- `notEmptyDate()` 
- `notEmptyDatetime()` 
- `notEmptyTime()` 

##notEmpty##
```php
$validator->notEmpty($field, $message = null, $when = null)
```
空を認めません。具体的には '' や、 null 、 [] といった値（空の配列）です。これもラッパーメソッドではありません。
`allowEmpty`と同じく、3.7から非推奨となり、以下のメソッドの使用が推奨されています。

- `notEmptyString()`
- `notEmptyArray()`
- `notEmptyFile()`
- `notEmptyDate()` 
- `notEmptyDatetime()` 
- `notEmptyTime()` 

##notBlank##
```php
$validator->notBlank($field, $message = null, $when = null)
```
空を認めないところは`notEmpty`と同じですが、相違点は空白文字も認めないところです。
全角スペースは通してしまうので、注意が必要です。

##alphaNumeric##
```php
$validator->alphaNumeric($field, $message = null, $when = null)
```
英数字だけであることをチェックします。
内部的にはなんだか見慣れない正規表現が使われています。

```Validation.php
public static function alphaNumeric($check)
{
    if (empty($check) && $check !== '0') {
        return false;
    }
    return self::_check($check, '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]+$/Du');
}
```

これは、[Unicodeカテゴリ](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/character-classes-in-regular-expressions#word-character-w)でチェックされていることがわかります。

そのため日本語は弾いてくれません:cry:
`/^[a-zA-Z0-9]+$/`のような正規表現を使いましょう。

##lengthBetween##
```php
$validator->lengthBetween($field, array $range, $message = null, $when = null)
```
数字の範囲を配列で渡して指定します。

##creditCard##
```php
$validator->creditCard($field, $type = 'all', $message = null, $when = null)
```
クレジットカードの形式かどうかをチェックします。`$type`はallとfastから指定できます。
allは各クレジットカード会社の形式に沿っているかどうかチェックし、fastはすべての形式を一度だけチェックします。つまり、

```php
$cards = [
    'all' => [
        'amex' => '/^3[47]\\d{13}$/',
        'bankcard' => '/^56(10\\d\\d|022[1-5])\\d{10}$/',
        'diners' => '/^(?:3(0[0-5]|[68]\\d)\\d{11})|(?:5[1-5]\\d{14})$/',
        'disc' => '/^(?:6011|650\\d)\\d{12}$/',
        'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
        'enroute' => '/^2(?:014|149)\\d{11}$/',
        'jcb' => '/^(3\\d{4}|2131|1800)\\d{11}$/',
        'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
        'mc' => '/^(5[1-5]\\d{14})|(2(?:22[1-9]|2[3-9][0-9]|[3-6][0-9]{2}|7[0-1][0-9]|720)\\d{12})$/',
        'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
        'switch' => '/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
        'visa' => '/^4\\d{12}(\\d{3})?$/',
        'voyager' => '/^8699[0-9]{11}$/'
    ],
    'fast' => '/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/'
];
```
こういうことですね。

##greaterThan##
```php
$validator->greaterThan($field, $value, $message = null, $when = null)
```
`$value`で指定した数字を超えることをチェックします。
`$field > $value`

##greaterThanOrEqual##
```php
$validator->greaterThanOrEqual($field, $value, $message = null, $when = null)
```
`$value`で指定した数字以上であることをチェックします。
`$filed >= $value`

##lessThan##
```php
$validator->lessThan($field, $value, $message = null, $when = null)
```
`$value`で指定して数字未満であることをチェックします。
`$field < $value`

##lessThanOrEqual##
```php
$validator->lessThanOrEqual($field, $value, $message = null, $when = null)
```
`$valueｄ`で指定した数字以下であることをチェックします。
`$field <= $value`

##equals##
```php
$validator->equals($field, $value, $message = null, $when = null)
```
`$value`で指定した数字と一致することをチェックします。緩やかな比較(==)が使われます。
`$field == $value`

##notEquals##
```php
$validator->notEquals($field, $value, $message = null, $when = null)
```
`$value`で指定した数字と一致しないことをチェックします。緩やかな比較(!=)が使われます。
`$field != $value`

##sameAs##
```php
$validator->sameAs($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールドと一致することをチェックします。厳密な比較(===)が使われています。
`$field === $secondField`

##notSameAs##
```php
$validator->notSameAs($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールドと一致することをチェックします。厳密な比較(!==)が使われています。
`$field !== $secondField`

##equalToField##
```php
$validator-> equalToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールドと一致することをチェックします。緩やかな比較(==)が使われています。
`$field == $secondField`

##notEqualToField##
```php
$validator->notEqualToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールドと一致することをチェックします。緩やかな比較(!=)が使われています。
`$field != $secondField`

##greaterThanToField##
```php
$validator->greaterThanToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールドを超えることをチェックします。
`$field > $secondField`

##greaterThanOrEqualToField##
```php
$validator->greaterThanOrEqualToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールド以上であることをチェックします。
`$filed >= $secondField`

##lessThanToField##
```php
$validator->lessThanToFieldToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールド未満であることをチェックします。
`$field < $secondField`

##lessThanOrEqualToField##
```php
$validator->lessThanOrEqualToField($field, $secondField, $message = null, $when = null)
```
バリデーション対象の配列の他のフィールド以下であることをチェックします。
`$field <= $secondField`

##containsNonAlphaNumeric##
```php
$validator->containsNonAlphaNumeric($field, $limit = 1, $message = null, $when = null)
```
英数字が含まれているかどうかをチェックします。`$limit`を指定すると、その回数だけ英数字が含まれていることを要求します。

alphaNumericとは違う正規表現が使われています。

```php
$matches = preg_match_all('/[^a-zA-Z0-9]/', $check);
```

##date##
```php
$validator->date($field, $formats = ['ymd'], $message = null, $when = null)
```
日付の形式かどうかをチェックします。`$formats`をymd形式で指定することができます。
指定できる形式は以下のとおりです。

- `dmy` 27-12-2006 or 27-12-06 
- `mdy` 12-27-2006 or 12-27-06 
- `ymd` 2006-12-27 or 06-12-27 
- `dMy` 27 December 2006 or 27 Dec 2006
- `Mdy` December 27, 2006 or Dec 27, 2006
- `My` December 2006 or Dec 2006
- `my` 12/2006 or 12/06 
- `ym` 2006/12 or 06/12 
- `y` 2006 

日付の区切りは`-` ` `(スペース) `/` `.`が使えます。

##datetime##
```php
$validator->dateTime($field, $formats = ['ymd'], $message = null, $when = null)
```
dateとtimeの両方をチェックします。
形式は、dateメソッドでしていしたものに加えて、`ISO8601`を指定することでISO8601形式を使用することができます。

##time##
```php
$validator->time($field, $message = null, $when = null)
```
時刻の形式かチェックします。
具体的には、`(HH:MM)`か、`([H]H:MM[a|p]m)`の形式です。

##localizedTime##
```php
$validator->localizedTime($field, $type = 'datetime', $message = null, $when = null)
```
地域化された日付形式化チェックします。
具体的には`\Cake\I18n\Time`のメソッドを使用してチェックされます。
形式は以下の３つから選ぶことができます。

- datetime \Cake\I18n\Time::parseDateTime()`
- date \Cake\I18n\Time::parseDate()`
- time \Cake\I18n\Time::parseDate()`

##boolean##
```php
$validator->boolean($field, $message = null, $when = null)
```
`true, false, 0, 1, '0', '1'`に一致するかどうかチェックします。
文字列の0と1も許容します。

##decimal##
```php
$validator->decimal($field, $places = null, $message = null, $when = null)
```
decimal型、つまり十進数小数であることをチェックします。
`$place'(小数の桁数)を指定できます。

- null => カンマ`.`が含まれている必要はない 
- true => 小数部分が0より大きいか、`float`か`double`型であることが要求される。カンマ`.`が含まれている必要がある。
- 1..N => 数字を指定すると、その桁数小数部分が存在することが要求される。

##email##
```php
$validator->email($field, $checkMX = false, $message = null, $when = null)
```
`$checkMX`を指定すると、MXレコードを含めてチェックします。

##ip##
```php
$validator->ip($field, $message = null, $when = null)
```
IPv4または、IPv6の形式がどうかチェックします。

##ipv4##
```php
$validator->ipv6($field, $message = null, $when = null)
```

##ipv6##
```php
$validator->ipv6($field, $message = null, $when = null)
```
##minLength##
```php
$validator->minLength($field, $min, $message = null, $when = null)
```

mb_strlenをしようして、`$min`で指定した文字数以下かチェックします。
`mb_strlen($check) >= $min`

##maxLength##
```php
$validator->maxLength($field, $max, $message = null, $when = null)
```

mb_strlenをしようして、`$max`で指定した文字数以上かチェックします。
`mb_strlen($check) <= $max`

##minLengthBytes##
```php
$validator->minLengthBytes($field, $min, $message = null, $when = null)
```

strlenをしようして、`$min`で指定したバイト数以下かチェックします。
`strlen($check) >= $min`

##maxLengthBytes##
```php
$validator->maxLengthBytes($field, $max, $message = null, $when = null)
```

strlenをしようして、`$max`で指定したバイト数以上かチェックします。
`strlen($check) <= $max`

##numeric##
```php
$validator->numeric($field, $message = null, $when = null)
```
[is_numeric](https://www.php.net/manual/ja/function.is-numeric.php)を使用してチェックされているので、
16進数表記`0x539`や`1337e0`なども認められます。

##naturalNumber##
```php
$validator->naturalNumber($field, $message = null, $when = null)
```
自然数かどうかを、正規表現を用いてチェックしています。
０は自然数に含みません。

```php
/^[1-9][0-9]*$/
```

##nonNegativeInteger##
```php
$validator->nonNegativeInteger($field, $message = null, $when = null)
```
0以上の整数か、つまり0を含む自然数かどうかチェックしています。
実際、参照先はnaturalNumberと同じく`\Cake\Validation\Validation::naturalNumber()`です。

```php
/^(?:0|[1-9][0-9]*)$/
```

##range##
```php
$validator->range($field, array $range, $message = null, $when = null)
```

`lengthBetween`と似ていますが、こっちは数字が有効の範囲化チェックします。
`$range`で指定する数字は、float型もOKです。

##url##
```php
$validator->url($field, $message = null, $when = null)
```

スキーマ、IP、ドメインネーム、パス、クエリー、フラグメントの部分に分けられて判定されます。
スキーマは省略されていても構いません。

##urlWithProtocol##
```php
$validator->url($field, $message = null, $when = null)
```

前述の`url`と同じ参照先ですが、こちらはスキーマの指定が必須になります。
スキーマは以下の通りです。
`http(s)/ftp(s)/file/news/gopher`

##inList##
```php
$validator->inList($field, array $list, $message = null, $when = null)
```

フィールドが`$list`で指定された配列の要素の中にあるか、`in_array`でチェックします。
`strval`で文字列に変換してから比較してるので、int型を指定しても特に問題はありません。
(フォームから送られる数字は、通常文字列です。)

例

```php
$validator->inList('fruit', ['apple', 'banana', 'lemon'])
```

'apple' => OK
'Kiwi' => NG
'APPLE' => NG

##uuid##
```php
$validator->uuid($field, $message = null, $when = null)
```

[UUID](https://tools.ietf.org/html/rfc4122)は、一位となる識別子です。
8桁-4桁-4桁-12桁の16進数で構成されています。

##uploadedFile##
```php
$validator->uploadedFile($field, array $options, $message = null, $when = null)
```
ファイル形式かどうか調べます。これは、`\Psr\Http\Message\UploadedFileInterface`のインスタンスかどうかで判定しています。
`$option`を指定すると、以下の更に以下を指定することができます。

- `types` ファイルの拡張子を指定する。
- `minSize` ファイルの最小バイト数を指定する。
- `maxSize` ファイルの最大バイト数を指定する。
- `optional` ファイルがオプションかどうか

##latLong##
```php
$validator->latLong($field, $message = null, $when = null)
```

##latitude##
```php
$validator->latitude($field, $message = null, $when = null)
```

##longitude##
```php
$validator->longitude($field, $message = null, $when = null)
```

##ascii##
```php
$validator->ascii($field, $message = null, $when = null)
```

##utf8##
```php
$validator->utf8($field, $message = null, $when = null)
```

##utf8Extended##
```php
$validator->utf8Extended($field, $message = null, $when = null)
```
##integer##
```php
$validator->integer($field, $message = null, $when = null)
```
整数かどうかをチェックするので、fload型は受け付けません。
[`is_int`](https://www.php.net/manual/ja/function.is-int.php)を使ってチェックしていますが、`フォームから来た洗の場合は常に文字列として扱われるため、
そのような場合には正規表現を用いてチェックされています。

```Validation.php
if (!($value) || is_float($value)) {
    return false;
}
if (is_int($value)) {
    return true;
}

return (bool)preg_match('/^-?[0-9]+$/', $value);
```

##isArray##
```php
$validator->isArray($field, $message = null, $when = null)
```

[`is_array`](https://www.php.net/manual/ja/function.is-array.php)でチェックされています。

##isScaler##
```php
$validator->isScaler($field, $message = null, $when = null)
```

[`is_scaler`](https://www.php.net/manual/ja/function.is-scalar.php)でチェックされています。

##hexColor##
```php
$validator->hexColor($field, $message = null, $when = null)
```

16進数文字が6回出現するかどうかでチェックしています。

##multipleOptions##
```php
multipleOptions($field, array $options = [], $message = null, $when = null)
```

複数選択セレクトボックスは、配列で送られてくるので、その形式になっているかチェックします。

`$options`は、以下の選択肢を指定することができます。

- in => `in_array`で、特定の要素が存在するかチェックします。
- max => 指定された数を超える数選択されていることをチェックします。
- min => 指定された数未満選択されていることをチェックします。
- caseSensitive => tureを指定すると、inでチェックするとき、大文字小文字を無視します。

##hasAtLeast##
```php
$validator->hasAtLeast($field, $count, $message = null, $when = null)
```

これは、[hasManyまたはbelongsToManyにおける特別な配列のキー`__ids`](https://book.cakephp.org/3/ja/orm/saving-data.html#hasmany)の数と比較するものです。

hasManyアソシエーションを保存しようとするとき、以下のような`_ids`形式を使うことができます。

```php
$data = [
    'title' => '私の新しい記事',
    'body' => '本文',
    'user_id' => 1,
    'comments' => [
        '_ids' => [1, 2, 3, 4]
    ]
];
```

この`_ids`の数が`$count'で指定したか数未満のとき、バリデーションエラーが発動します。

##hasAtMost##
```
$validator-> hasAtMost($field, $count, $message = null, $when = null)
```

フィールドの`_ids`が`$count`以下かどうかをチェックします。

##regex##
```php
$validator->regex($field, $regex, $message = null, $when = null)
```

`$regex`に、正規表現を指定します。