見出し画像

【JavaScript】半角ハテナ「?」をmatchで検索したいのにUncaught SyntaxError: Invalid regular expressionが出る

「この文章には半角ハテナが含まれているか?」をmatchで調べようとしたらUncaught SyntaxError: Invalid regular expressionで落ちた話。

結論

こう。

const check_text = "この文章中に半角ハテナはあるか?"

if(check_text.match('/\?/')){
  console.log("あるよ");
}else{
  console.log("ないよ");
}

matchの引数として渡す比較用文字列を、正規表現であることを明記した上でエスケープしておく。ただクオーテーションで囲んでバックスラッシュでエスケープしただけだとダメ。

文字列検索をするmatch()

文字列.match("検索文字列")

を使うことで、「文字列」の中に「検索文字列」という文字列が含まれているかを確認することが出来ます。ここまでは簡単。

match()の引数には正規表現が使える

正規表現って何?という説明はちょっと骨が折れるので各自ググってください。ものすごくざっくり言うと、【「(何文字かの数字)_(何文字かの文字列).jpg」という構成になっている文字列を探したい時、「/d*_*.jpg」みたいな書き方をすることで検索できる】という便利な機能です。この文字列は電話番号として正しい形になってるか?みたいなのを調べたい時に使います。

match()の引数にそれが渡せるのは便利ですね。

半角ハテナは、正規表現では「直前のパターンの0~1回の繰り返し」を表す意味をもつ記号である

正規表現ではたとえば、「0*」と書くと「数字のゼロの、0回以上の任意の回数の繰り返し」を示します。「*」という記号には「直前の文字が0回以上繰り返されていること」という意味があります。あってしまいます。
そして同じように半角ハテナにも、「直前の文字の0~1回の繰り返し」という意味があってしまいます。

match()の引数として半角ハテナを一つ渡すと、「なんか解らんけど0~1回の繰り返しって言われたけど、何の繰り返しか解らん」って言われる

「直前の文字の繰り返しを探してね」という命令だけが渡ってしまうので、意味わからん。って言われてプログラムはエラーを吐いて止まってしまいます。

ついでに、matchの引数として「hoge?」みたいな文字列を渡すと、【「hog」と「eの0回か1回の繰り返し」と判断されるので、「hoge?」と比較すればもちろん「あるよ」になりますが、「hog」や「hogee」みたいな文字列と比較したときにも「あるよ」と判断されてしまうので注意が必要です。

ただエスケープしただけだとダメっぽい

正規表現で使う特有の記号(/、*、?、^など)を、それそのものとして検索したい時、つまり今回の様に、半角ハテナを半角ハテナとして検索したい時は、「エスケープ」という処理を行います。
それそのものとして使いたい文字の直前に「\」を入れる事でそれそのものとして検索することができるのですが、

const check_text = "この文章中に半角ハテナはあるか?"

if(check_text.match('\?')){
  console.log("あるよ");
}else{
  console.log("ないよ");
}

と、エスケープしても「なんかよくわからんもん繰り返せって言われてるんだけど」のエラーが消えません。なんでや。

今から正規表現で話をしますね。ハテナはエスケープします。と二段構えで教えて上げる必要がある

まず、検索対象文字列を / / で囲むことにより、「この中は正規表現です!」と宣言します。(もちろん、変数ではなく文字列であることを示す為に全体をクォーテーションで囲むのはお忘れ無く)

check_text.match('/?/')

さらに、「ハテナはエスケープします!」と伝える為にハテナの前にバックスラッシュを付与します

check_text.match('/\?/')

これでやっとハテナをハテナ単品として検索することが出来ます。

ちなみに、ハテナを含む文字列(例:hoge?を検索したい場合)

check_text.match('/hoge\?/')

正規表現ですよーと宣言した上で、ハテナだけエスケープします。

そのほか、*とか^とか\とか"とかも似たような処理が必要になります。
(詳しくは正規表現でググって見てください)

この記事が気に入ったらサポートをしてみませんか?