正規表現考える
<?php $str = "/content/hoge/fuga/piyo/ドメイン/hoge.html"; $regular1 = "/\/content\/(.*?)\/(.*?)\/(.*?)\//"; //[/content/hoge/fuga/piyo/] $regular2 = "/^\/([^\/]*\/){4}/"; //[/content/hoge/fuga/piyo/] $regular3 = "/^\/((.*?)\/){4}/"; //[/content/hoge/fuga/piyo/] preg_match($regular1, $str, $matches1); preg_match($regular2, $str, $matches2); preg_match($regular3, $str, $matches3); echo "元: ".$str.PHP_EOL; echo PHP_EOL; echo "正規表現: ".$regular1.PHP_EOL; echo "パターン全体にマッチしたテキスト: ".$matches1[0]; echo PHP_EOL; echo PHP_EOL; echo PHP_EOL; echo "正規表現: ".$regular2.PHP_EOL; echo "パターン全体にマッチしたテキスト: ".$matches2[0]; echo PHP_EOL; echo PHP_EOL; echo PHP_EOL; echo "正規表現: ".$regular3.PHP_EOL; echo "パターン全体にマッチしたテキスト: ".$matches3[0]; echo PHP_EOL; echo PHP_EOL;
パターンマッチを確認
matches
matches を指定した場合、検索結果が代入されます。 $matches[0] にはパターン全体にマッチしたテキストが代入され、 $matches[1] には 1 番目のキャプチャ用サブパターンにマッチした 文字列が代入され、といったようになります。
1. 正規表現: /\/content\/(.?)\/(.?)\/(.*?)\//
Array ( [0] => /content/hoge/fuga/piyo/ [1] => hoge [2] => fuga [3] => piyo )
2. 正規表現: /^\/([^\/]*\/){4}/
Array ( [0] => /content/hoge/fuga/piyo/ [1] => piyo/ )
3. 正規表現: /^\/((.*?)\/){4}/
Array ( [0] => /content/hoge/fuga/piyo/ [1] => piyo/ [2] => piyo )
【Laravel】クエリビルダーでスペース区切りの複数ワード検索を行う
所感とか
所感
🤪 考えるのすごい時間かかったのに、寝たら一瞬で思いついた. 睡眠は大事.
大事だと思ったこと
ポイント
- 半角スペースを全角スペースにする:
mb_convert_kana($request->words, 's');
- スペースごとに配列に格納:
preg_split('/[\s]+/', $request->words);
- Illuminate\Support\Collectionで配列要素全てに処理を追加:
Collection::make($strArry)->map(function($p){return "%".$p."%";})->toArray();
- それぞれごとにwhere句を形成する:
$query->where(function($query)use(...){});
を複数使うとこでまとまったwhere句を形成できる - 最初に受け取ったinputを引き出せる:
$request->session()->getOldInput()
ソース
// 検索ワード[aaa bbb ccc] の場合 select * from `products` where (`title` like "%aaa%" and `title` like "%bbb%" and `title` like "%ccc%") or (`description` like "%aaa%" and `description` like "%bbb%" and `description` like "%ccc%");
- Model(Search.php)
<?php static function search(Request $request) { $products = self::query(); $hasParam = true; $search_words; if(isset($request->words)) { //検索ワードを分割 if(isset($request->words)) { //半角スペースを全角スペースにする $request->words = mb_convert_kana($request->words, 's'); //スペースごとに配列に格納 $strArry = preg_split('/[\s]+/', $request->words); //use Illuminate\Support\Collectionで配列要素全てにワイルドカード(%)を追加 //$pが配列の要素ひとつずつになる. その要素に処理をして,returnで元の要素と入れ替えるイメージ $search_words = Collection::make($strArry)->map(function($p) { return "%" . $p . "%"; })->toArray(); } $count = count($search_words); //title, descriptionそれぞれごとにwhere句を形成 $products = $products ->where(function($query)use($search_words){ foreach($search_words as $search_word) { $query->where('title', 'like', $search_word); } }) ->orwhere(function($query)use($search_words){ foreach($search_words as $search_word) { $query->where('description', 'like', $search_word); } }); } else { $hasParam = false; $products = $products; } $result = []; //初期表示にメッセージが出ないようにする if($products->count() <= 0 && $hasParam){ $result['message'] = "検索結果は0件です"; } else { $result['message'] = ""; } $result['products'] = $products; return $result; }
- Controller(Controller.php)
<?php public function index(Request $request) { $products = Search::search($request); $message = $products['message']; $products = $products['products']; if($message) { //検索結果が0件の場合 return view('index', [ 'products' => $products, 'inputs' => array_merge($request->input(), $request->session()->getOldInput()), 'message' => $message ]); } //検索結果が1件以上の場合 return view('akashic-game.products.index', [ 'products' => $products, 'inputs' => array_merge($request->input(), $request->session()->getOldInput()), 'message' => $message ]); }
- View(index.blade.php)
@if (isset($message)) <p>{{ $message }}</p> @else <form action="{{ action('Controller@index') }}" method="GET"> <fieldset> <div> <input type="text" name="words" value="@if(!empty($inputs['words'])){{ $inputs['words'] }}@endif"> </div> <button type="submit">検索</button> </fieldset> </form> <div> @forelse($items as $item) <li>{{ $item->title }} : {{ $item->description }}</li> @endforeach </div>
display:none の時のimgサイズ
へーと思ったのでメモ。
display:none の時のimgサイズは 0*0pix になる
ソースはこんな感じ
<body> <div class="wrap"> <button id="item">さーばる</button> <button id="reset" style="display: none;">もどす</button> <div style="margin-top: 1em;"> <img alt="さーばる" src="animal_serval.png" style="display: none; height: 30%;"> </div> </div> <script> $('#item').click(function () { $(this).hide(); $('img').show(); $('#reset').show(); }); $('#reset').click(function () { $(this).hide(); $('img').hide(); $('#item').show(); }); </script> </body>