あじちゃんの備忘録。

〜ここはメモ帳です

正規表現考える

<?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】クエリビルダーでスペース区切りの複数ワード検索を行う

所感とか

所感

🤪 考えるのすごい時間かかったのに、寝たら一瞬で思いついた. 睡眠は大事.

大事だと思ったこと

  • ワードをどの要素にどういう条件で絞り込むのかを明確にすること
  • はじめに目的とするSQLを書いてみること
  • 要素ごとにまとめてwhere句を作っていくこと
  • 正規表現は何パターンか覚えておきたいところ

ポイント

  • 半角スペースを全角スペースにする: 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 になる

f:id:azix:20180619150505p:plain
表示中のサイズ

f:id:azix:20180619150953p:plain
非表示中のサイズは0になる


ソースはこんな感じ

<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>