正規表現が使えるようになると、特に文字列の検索や置換が効率的に行えます。まずは「こんなパターンを覚えておくだけでも便利!」というものをご紹介しましょう。
第14章で見たようにJavaScriptのプログラム中でも正規表現を使えますが、VS Codeの[編集]メニューの[フォルダを指定して検索]を使うと、そのパワーを簡単に確認できます。
VSコードの一番左側の「アクティビティバー」の虫眼鏡のアイコンをクリックすると、アクティビティバーの右の欄の「サイドバー」が「検索・置換」用に変化します。MS Wordなどと同じように検索や置換ができますが、ここで注目していただきたいのが「検索」欄の一番右側にある「.*」が書かれたアイコンです。これを「オン」の状態にすることで正規表現を使った検索や置換ができるようになります。
早速使ってみましょう。
jsdataのフォルダを開いください.*」の書かれた正規表現のアイコンをクリックしてオンにします(オンになると、アイコンの周囲に枠が表示されます)これで、「検索」欄に「正規表現」を入力すれば、このフォルダ内にあるファイルの、その正規表現を含むすべての行が下に表示されるようになりました。
たとえば、まず単純に「console」と入力してみてください。するとconsoleが入っている行がたくさん表示されます。console.logが含まれている行がたくさんありますが、console.timeやconsole.timeEndなどが含まれる行も表示されます。
ここで、オブジェクトconsoleのメソッドの内console.log以外のものが使われている行を表示してみましょう。
console\.[a-km-z]」と入力してみてくださいすると、console.timeやconsole.timeEndなどが含まれる行が表示されるようになったはずです。console.logが含まれている行でも、console.timeなどが含まれていれば表示されます。
上で入力した検索対象文字列「console\.[a-km-z]」には、メタ文字あるいは特殊文字と呼ばれものが含まれています。ここで、よく使われるメタ文字を紹介しておきましょう。
.」「.」(半角ピリオド。「ドット」と読まれます)は「任意の1文字」にマッチします。ただし検索欄に書いた文字列のように直前の文字が「\」(バックスラッシュ)である場合は、この意味が打ち消されます(つまり単純に文字「.」として解釈されます)。
\」すぐ上に書いたように「.」は、任意の1文字にマッチするメタ文字(特殊文字)なのですが、直前に「\」があると、この特別な意味がなくなり、単に「.」(ピリオド)とマッチするようになります。検索対象文字列のうち、「console\.」までの部分を見てみると、「console」は単純な文字列ですので、「console\.」で「console」のあとに「.」が書かれたものがマッチすることになります。したがって、consoleオブジェクトのメソッドやプロパティをこれで探すことができます。
[...]次に、「console\.[a-km-z]」の「\.」に続く「[a-km-z]」に注目しましょう。[...]という表現で、「...」に指定された任意の文字にマッチします。たとえば[ab]で「a」あるいは「b」にマッチします。
上の例ではここにa-km-z]が指定されています。このa-kは、アルファベットの小文字のaからkの文字を表します。つまり、[abcdefghijk]と書いても同じことになりますし、少しひねくれた表現を使えば[a-de-hi-k]などと書いても同じことになります。
a-kの後ろにあるm-zは、同様に小文字のmからzのいずれかを表します。
この「[a-km-z]」をわかりやすい言葉で表すと、アルファベット小文字の「l」(エル)以外ということになります。
というわけで、検索対象文字列「console\.[a-km-z]」は「console.」のあとに「l」(エル)以外のアルファベット小文字で始まる文字列を検索するのに使うことができるわけです。メソッド名は小文字で始まりますので、「console\.[a-km-z]」でこの目的が果たせることになります。
なお、[...]の...の部分には、a-kなどのほか次のように、「文字の範囲」を指定することもできます。
[A-Z] ── 大文字のAからZのいずれか[0-9] ── 数字の0から9のいずれか日本語の文字(漢字や仮名)についても、現在のJavaScriptのコードについては、次のような表現を使って文字の範囲を表すことができます。ただし、プログラミング言語やツール、OSなどの環境(どのような文字コードを使っているか)などによって、うまく動かないケースもあるので、注意が必要です。
[0-9] ── 全角の数字の0から9のいずれか[あ-お] ── ひらがなの「あいうえお」のいずれかJavaScriptで日本語の範囲を指定する方法については、次のようなページを参考にしてください(「JavaScript 正規表現 漢字の範囲」といった表現でウェブ検索をしてみてください)。
^」「[a-km-z]」で、アルファベット小文字の「l」(エル)以外を表すことができますが、じつは、このような「〜以外」を表すメタ文字「^」も用意されています(「^」は「ハット」と呼ばれます)。
上の検索の目的はconsole.log以外のconsoleオブジェクトのメソッドを探すことなので、「[a-km-z]」の代わりに「[^l]」と書いてもこの目的を果たせることになります。このように書くと、たとえばconsole.Abcdというメソッドがあったとすれば、これもマッチすることになります。実際はconsoleに大文字で始まるメソッドはないので、[a-km-z]と書いても[^l]と書いても結果は同じになるわけです。
consoleのメソッドで「l」で始まるものはconsole.logだけなので、上の方法でよいのですが、厳密にやるには、下で説明する他の方法を使うことになります。
*」と「+」上の例には使われていませんが、正規表現では文字「*」や「+」も頻繁に使われます。
たとえば「getElement.*\(」を検索欄に入力してみてください。
.」── 任意の1文字*」── 前の文字の0個以上の繰り返し\(」── 文字「(」(第14章の正規表現の例で見たように(...)はorの項目をまとめるために使われるので、「\」でエスケープしてメタ文字としての役割をなくします)この結果getElementのあとに何文字か続いた後に「(」がくるものが検索されます。平たく言えば、getElementで始まる関数を探すことができるわけです。検索結果には、getElementByIdやgetElementsByClassNameが使われている行が表示されているはずです。
この目的では「getElement.+\(」でも同じことになるはずです。
+ ── 前の文字の1個以上の繰り返し厳密には「getElement[a-zA-Z]+\(」などとすればよいのでしょうが、目的が果たせる正規表現さえ入力すればよいわけですから、検索をしたい場合は、結構適当に試してみるとよいでしょう。
JavaScriptのコード中でマッチするか調べてなにか処理をするという場合は、ある程度きちんと考えないと目的が果たせないかもしれませんので、慎重さが求められます。
^」と「$」「行の始まりにある文字列で探したい」、逆に「行の終わりの文字列で探したい」という場合に役立つのが「^」と「$」です。
例をあげてみましょう。
^ *//」 ── 行の始まりがJSのコメントになっているもの。ただし、スペース文字が前にあってもよい-->[ \t]+$」 ── 行の終わりがHTMLのコメントの終わりになっていて、そのあとに、(余分な)タブやスペース文字が続いているもの(「\t」は「タブ」を表す)「[0-9]」や「[a-z]」などよく使われる範囲を表す表現には、\と組み合わせた短い表記法も用意されています。
\d ── [0-9]と同じ\D ── [^0-9]と同じ\l ── [a-z]と同じ(lower case letters)\L ── [^a-z]と同じ正直なところ、筆者は覚えるのが面倒なので [0-9] とか [a-z] のほうを使ってしまうことが多いです。読む人もこちらのほうがわかりやすいと思うのですよね...。
あと次のようなものも用意されています。筆者自身はあまり使わないように思いますが。
\b」 ── 区切り文字\B」 ── 区切り文字以外\w」 ── すべての半角英数字と「_」(アンダースコア)\W」 ── 半角英数字と「_」以外(?!...)」最初に「console\.[a-km-z]」という表現を、console.log以外のconsoleのメソッドを探すのに使いましたが、この表現には少し問題があります。console.log以外に、「l」で始まるメソッドがある場合は見つけられません。
もっと、厳密に指定したい場合に使えるのが「(?!...)」のパターンです。たとえば、「console\.(?!log)」とすることで、「console.」のあとに「log」がこないものを探すことができます。
実際に検索してみると、console.timeやconsole.timeEndなどが含まれる行が表示されます(この場合には、「console\.[a-km-z]」をした場合と結果は変わりませんが)。
今度は、本文の第14章の正規表現の例に出てきた「or」を表す「|」と組み合わせて見ましょう。たとえば、console\.(?!(log|time))とすると「console.のあとにlogでもtimeでもないものが続いたもの」とマッチするようになります。
実際に検索してみるとconsole.tableとconsole.clearがマッチしますね(メソッドの意味を忘れちゃったら本文でもう一度確認してください!)。
メタ文字について、さらに詳しくは、たとえば次のようなページを参照してください。
正規表現について、簡単に説明しました。
まあ、ともかくいろいろ試してみてください。まずは検索で。「習うより慣れよ」的な感じもありますので。
より詳しく知りたくなったら、次のページなどを参照してください。「JavaScript 正規表現」などといった文字列でウェブ検索してみて、自分のフィーリングに合う説明を探してもよいでしょう。