テストにおいて任意の文字列や数字を生成したい場合はfakerのwordやsentenceおよびnumberBetweenなどを使いますが、ある書式に準じた任意の文字列を生成したい場合もあります。
このようなケースではregexifyを使用します。
用法
インタフェースは以下のようになっています。
regexify(string $regex = '') :string
上記仕様だと引数の省略もできるように見えますが、省略した場合(引数に空文字を指定した場合と同等)に関しては戻り値も空文字になるようなので、あまり意味はないように思います。
と言うことで、引数には出力したい文字列の書式を意味する正規表現を指定します。
例えば4桁の数字3個をハイフンで結合した文字列が必要であれば以下のように記述します。
$faker->regexify('[0-9]{4}-[0-9]{4}-[0-9]{4}');
上記の実行結果としては「5643-4848-9379」のような文字列が返されます。
前回紹介したuniqueメソッドとの組み合わせも可能です。
for ($i=0; $i < 10; $i++) {
echo $faker->unique()->regexify('[0-9]')."\n";
}
上記の実行結果は以下の通り。
4
9
2
8
0
6
5
7
1
3
当然ながら、ループを11回以上実行しようとするとエラーになります。
注意点
regexifyの最大の弱点はマルチバイトコードに対応していないと言うことです。
例えば以下のような処理を実行してみます。
$faker->regexify('[あいう]');
期待しているのは「あ」「い」「う」のいずれかが返されることですが、結果としては謎の文字が返されます。
なお、上記程度であれば以下のような方法で期待した結果が得られます。
$faker->randomElement(['あ','い','う']);
ただし、選択の候補が多くなってくると苦しくなります。
やはり、以下のような表現ができると良いのですが…
$faker->regexify('[あ-ん]'); // 実際には期待された処理にならない
所感
そもそも今回の投稿はregexifyの基本的な使い方を紹介しつつ、弱点であるマルチバイトコードの扱いに関して代替案なり妥協案なりを探ってみようと思って、見切り発車的に始めたものです。
よって、本記事を書きながら思いついた方法をいくつか試してみたのですが、結局は有効な方法を見出せず、結果として地味な投稿になってしまいました。
ただ、改めて考えてみればregexifyを使いたい局面でマルチバイトを含む必要があるケースはあまりないように思います。
regexifyの用例としては、例えばISBN(978-N-NN-NNNNNN-N)のような特定の書式を持つデータのランダムな生成を目的とする場合が考えられますが、このようなケースで扱われる文字は数字とアルファベットの組み合わせが大半であるように思います。
regexifyは使える範囲で使うと言うことで(身も蓋もない結論)。