【CakePHP】Hashクラスの絞り込みで正規表現を使ってみる。
船舶時計を買おうかどうか迷っているfukasawaです。こんにちは。
フォルムに興奮するのですが、時計にしては少々お高いですよね。室内で使うので防塵機能は必要ないし、電波時計のほうが時間を合わせる手間が省けて楽だし、と考えるとなかなか悩ましいところです。
さて本題です。CakePHPを使って開発されている方にはお馴染みの、配列を操作するために使用するHashクラス(バージョン 2.1以前はSetクラス)ですが、絞り込みの条件としてどうやら正規表現が使えるらしいです。ということを一昨日くらいに知ったので、簡単に使い方について触れてみたいと思います。
※バージョン2.6.3、バージョン3.0.2で検証しています。
構文
公式サイトのHash パス構文にて要素を絞り込むためのマッチャの表を確認すると、一番下の行で以下のように書かれています。
[text=/.../] 正規表現 | ... と合致する値を持っている 要素に絞り込む。 |
こちらの構文を使って正規表現の絞り込みを行ってみます。
サンプルとして、本の情報を持つ簡単な配列を用意しました。こちらの配列に操作を行っていきます。(複雑になりそうなのでtagsをカンマ区切りにしたりと、シンプルな形にしています。)
$books = array(
array(
'Book' => array(
'id' => '5',
'title' => '魚のレシピ',
'author' => 'ジョージ・W・フィッシュ',
'price' => '2400',
'tags' => '洋書,魚'
)
),
array(
'Book' => array(
'id' => '4',
'title' => '肉のレシピ',
'author' => 'スティーブン・ミート',
'price' => '2900',
'tags' => '洋書,肉'
)
),
array(
'Book' => array(
'id' => '6',
'title' => 'きのこ栽培',
'author' => '椎武雄',
'price' => '1400',
'tags' => '和書,家庭菜園'
)
),
);
Hash::check()で使ってみる。
Hash::check()で使ってみます。
foreach($books as $book){
if(Hash::check($book,'Book[tags=/(^|,)(家庭菜園)(,|$)/]')){
debug($book);
}
}
foreach()の中でHash::check()を使用し、$book['Book']['tags']に"家庭菜園"というタグ(カンマ区切り)が含まれているかを正規表現で調べ、含まれていたらdebug()で出力しています。
出力結果は以下のとおりです。tagsに"家庭菜園"が含まれる"きのこ栽培"という本のみが出力されています。
Hash::extract()で使ってみる
同様に、Hash::extract()でも使ってみます。
debug(Hash::extract($books, '{n}.Book[title=/(肉|魚)/]'));
$books[n]['Book']['title']に"肉"もしくは"魚"を含むBookを抽出し、debug()で出力しています。
出力結果は以下のとおりです。
Hash::remove()で使ってみる
Hash::remove()でも使ってみます。
debug(hash::remove($books, '{n}.Book[title=/^(?!.*魚).*$/]'));
$booksから$books[n]['Book']['title']に"魚"を含んでいないBookを削除しています。出力結果は以下のとおりです。
まとめ
正規表現を使用する場合でも、find()するときは検索条件として指定してあげたほうが良い気がしますが、それ以外で配列を精査するときに使えるかもしれません。