使用可能な記号のバリデーションの正規表現を模索する


フロントエンドエンジニアの茶木です。

種別や管理コードなどは数字のみで管理したいものですが、実際は慣習などで記号を含む運用をする場合もありますよね。たとえば E01-44(a)v0.1/2022 など、これらを input から手入力するような場合、使用可能な記号を指定して、文字列にバリデーションをかけたいですね。

常套句 /^[○○]+$/

こういうときは正規表現で使用可能な文字だけで構成されているかを記述するのが筋です。

ある文字列だけを含むかどうかの判定なら `/^[○○]+$/` これが常套句です。英数字の判定は以下のとおりです。

const regexNumberAndAlphabet = /^[a-zA-Z\d]+$/
regexNumberAndAlphabet.test(text)

これは簡単ですね!

_(アンダースコア)や#(シャープ)も許可する

const regexNumAlpUnderScoreSharp = /^[a-zA-Z\d_#]+$/
regexNumAlpUnderScoreSharp.test(text)

[]の中に _ や # を書くだけなので、これは変わらず簡単です。

ところがエスケープが難しい・・・

さて、本題です、さらに記号をOKにしたいとなった場合に、ちょっと難しくなります。

たとえば、

!?_+*‘”`#$%&-^\@;:,./=~|[](){}<>

上記の記号もOKにしたいというようなときは、以下のように書きたいところ。

const regex =
  /^[a-zA-Z\d!?_+*'"`#$%&-^\@;:,./=~|[](){}<>]+$/;

しかし、この記述はエラーになります。なぜならエスケープが必要な文字がいくつかあるからです。
ならば、全部エスケープしちゃう手もありそうですが、エディタによっては不要なエスケープを警告しますし、エスケープ記号だらけだと、可読性落ちますよね・・・

でも、安心してください!
実は、正規表現の [] の中でエスケープが必要な文字は、それほど多くないのです。

エスケープが必要な文字

[] の中においては、意外にも3つだけです

  • \ バックスラッシュ:それ自体がエスケープ文字なので \\ とします
  • ] 閉じ角かっこ:[] の終了記号と混同するため \] とします
  • - ハイフン:[a-z] のように範囲を示す記号なので、 \- とします

特に - ハイフンが危険で [&-^] とかうっかり書こうものなら、&^ を文字コードで見たときの間の文字も全部許可してしまう範囲指定になってしまいます。エラーにならないので要注意です。

場合によってエスケープが必要な文字

  • ^ サーカムフレックス:[^a-z] のように [ の直後に書くとき否定演算子になるため \^ とします。それ以外の場所ではエスケープ不要です。

結論

const regex =
  /^[a-zA-Z\d!?_+*'"`#$%&\-^\\@;:,./=~|[\](){}<>]+$/;

[]の中では、 \ ] - この3つだけエスケープすれば大丈夫です。


{ } . * + この辺とかがエスケープいるんじゃないかと思ったら、逆にいらないというお話でした。混同が起きないときはつけなくて良いということですね。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Chaki Hironori

webライターもやってるフロントエンドエンジニアです。Reactは自信があります。またデザイン畑の出身で、気持ちのいいアニメーションやインタラクティブな表現は丁寧に手掛けます。好きなものは中南米の遺跡で、スペイン語が少しできます。