下手するとtrue false

グローバルフラグ(g)の問題点

グローバルフラグ(gを使用すると、正規表現は状態を保持するようになります。これが意図しない挙動を引き起こす原因となることがあります。

例えば、JavaScriptでは、グローバルフラグを使うと以下のような動作になります。

  • 正規表現を初めて実行すると、最初の一致を返します。
  • 次に同じ正規表現を呼び出すと、前回の位置から次の一致を探します。
  • もし一致が見つからなければ、次の文字列を調べるために最初から検索をやり直します。

このように、グローバルフラグを使うと複数回の一致を追跡する状態が保持されるため、意図しない挙動を引き起こすことがあります。

const regex = /^[^-_]([a-z0-9-_]{4,20})[^-_]$/gi;
const str = "hello-world";
console.log(regex.exec(str)); // 最初の一致を取得
console.log(regex.exec(str)); // 次の一致を取得

上記のコードでは、regex.exec()を2回呼び出していますが、最初の呼び出しで得られた一致位置が保持された状態で次の一致を探すため、場合によっては意図しない結果を得ることになります。


3. グローバルフラグの適切な使用方法

もし、正規表現を「一度きり」のマッチングに使用したい場合、グローバルフラグ(g)は必要ありません。グローバルフラグを省略することで、状態を保持せず、意図しない動作を防ぐことができます。

修正案

/^[a-z0-9][a-z0-9_-]{2,18}[a-z0-9]$/i

このように、グローバルフラグ(g)を外すことで、正規表現は最初に一致した部分だけを返します。さらに、この正規表現では文字列の先頭と末尾が小文字の英字や数字であることを保証し、中身にはハイフンやアンダースコアが含まれても構いませんが、先頭と末尾にはそれらが来ないようにします。

Ref