正規表現


🐱‍🏍 正規表現を使うきっかけ
  • ユーザーが入力した値を既存の配列の要素と比較し、一致する要素のみからなる新しい配列を作成したいです.
    (具体的には、ユーザーが検索ウィンドウに旅行先を入力した場合、その検索語を含む都市名を集めてドロップダウンリストに表示したいだけです.)
  • このとき、検索結果を大文字と小文字を区別せずに表示したいと思います.
  • 以前、ユーザの入力値と配列要素.ToLowerCase()私toUpperCase()メソッドを使用して各文字列を変換し、比較します.
  • この方法も同様に有効ですが、いろいろな方法を試してみようと思ったので、今回は正規表現を使いました.
  • 1.正規表現は?
    正規表現は、文字列に表示される特定の文字の組み合わせを検索するモードです.テキストで必要な情報(電話番号、URL、電子メールアドレスなど)を検索する場合にも使用できます.(テキスト内で特定の文字列を検索し、必要な文字列で置き換えることもできます.)
    正規表現は.match()私replace()などの文字列メソッドとともに使用します.
    2.正規表現の作成
    正規表現はモードとフラグで構成されます.
    (タグは必須ではなく、必要な検索条件の場合に使用されます.)
    正規表現を宣言するには、2つの方法があります.
    1つ目の方法は、通常の文字(スラッシュ"/"で包まれたパターン)を使用することです.
    パターンをスラッシュで囲むと、文字列を宣言するときに「」(引用符)を使用するように、正規表現を宣言するときに//(スラッシュ)を使用するのは気まずいかもしれません.
    let regexp = /ab+c/;
    2つ目の方法はRegExpオブジェクトのコンストラクション関数を呼び出すことです.
    let regexp = new RegExp("ab+c");
    この場合、スラッシュではなく、パターンに「」(引用符)を付けます.
    実際には、上記で宣言したregexpは、いずれの方法を使用してもRegExpのインスタンスになります.
    スラッシュを使用する最初の方法は静的です.コードを記述するときに、モードがわかっていれば使用できます.
    RegExpジェネレータ関数を呼び出す方法は、動的に生成された文字列を使用して正規表現を作成する必要がある場合に便利です.たとえば、ユーザーが入力した値に基づいて正規表現を作成する必要があります.
    -> 🙋‍♀️ユーザーの入力値を受信して正規表現を作成するために実装するので、RegExpジェネレータ関数を呼び出して正規表現を作成します.
    詳細な説明👇
    文字記号は、式を計算するときに正規表現をコンパイルします。 正規表現が変わらない場合は、文字記号を使用します。 たとえば、繰り返し文で正規表現を使用する場合は、文字記号を使用して正規表現を作成します。 正規表現は毎回再コンパイルされません。

    正規表現オブジェクトの作成者(「ab+c」)を使用します。 正規表現は実行時にコンパイルされます。 配列を変更したり、ユーザー入力などの外部未知のソースからインポートしたりする正規表現については、コンストラクション関数を使用します。

    ソース:RegExp - MDN
    3.私が作成したコード
    const cityList = [
            "Seoul",
            "London",
            "Paris",
            "San Francisco",
            "Berlin",
            "New York",
            "Tokyo",
    ];
    まず都市名の並びを用意しました.
    (バックエンドがあれば、データが届くかもしれませんが、バックエンドのない独立したプロジェクトなので、ハードコーディングしました.)
    const [destination, setDestination] = useState("");
    
    <input type="text" 
           placeholder="Where are you going?" 
           value={destination} 
           onChange={(e)=>setDestination(e.target.value)} />
    
    useState hookを呼び出すことでdestinationというstate変数が宣言されます.
    ユーザーがinputウィンドウに必要な宛先を入力すると、ターゲット変数はsetDestinationという関数で更新されます.
    let filteredList;
    
    const findList = (destination, cityList) => {
            filteredList = cityList.filter((city) => {
                    const regexp = new RegExp(destination, "gi");
                    return city.match(regexp);
            });
    };
    filteredList変数を宣言します.
    findList関数は、パラメータとしてユーザ入力値(destination)と、上にハードコーディングされた都市名リスト(cityList)を受け入れる.
    .filter()メソッドを使用してcityListの都市名とユーザー入力値を比較します.
    一致する都市名をfilteredListに保存したいだけです.
    正規表現が作成されます.
    RegExpオブジェクトのコンストラクション関数を呼び出します.
    一致するモードにユーザー入力値を入れます.
    フラグはgとiを使用します.
    gタグ:gタグがない場合は、パターンに一致する最初の結果のみが返されますが、gタグを追加すると、パターンに一致するすべての内容が検索されます.グローバル検索とも呼ばれます.
    (リストに一致するすべての値を見つけたいので、gタグを付けました.)
    iフラグ:大文字と小文字を区別しない検索に使用します.(case insensitive)
    (ユーザは大文字入力も小文字入力もできるので、iタグを付けた.)
    city.match(regex)を呼び出して、文字列cityでregexpに一致する文字列を検索します.
    一致する部分文字列がある場合は、一致する文字列を最初の要素とする配列を返します.
    一致する文字列がない場合はnullを返します.
    最後に.一致する文字列がfilter()メソッドで見つかった場合にのみ、filteredListに格納されます.
    4.終了
    あとは各都市を各画面に表示すればいいです.
    filteredList.map((city,i)=><CityItem key={i} city={city}/>);
    このようにmap()メソッドを使用して、都市を要素に1つずつ入れてレンダリングします!
    そしてCSSを使って終わりました!
    参考資料📝
    Patterns and flags : https://javascript.info/regexp-introduction
    正規表現-MDN:https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
    String.prototype.match() - MDN : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/match
    Array.prototype.filter() - MDN : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter