🦍

JavaScriptの正規表現でgフラグを使う際は気をつけた方が良い

2024/05/29に公開1

はじめに

先日こちらのツイートが流れてきました。

https://x.com/jjenzz/status/1794891346643497418

動画内では次のことをやっていました。
何が起きているのか、まったくわからなかったので気になってこの挙動について調べて備忘録として残します。

> const r = /boop/g
undefined
> r.test("boop")
true
> r.test("boop")
false
> r.test("boop")
true
> r.test("boop")
false
> 

gフラグとは

JavaScriptを書いている方は一度くらいは/foo/gみたいな正規表現を書いたことがあるかと思います。
このgフラグをつけることで文字列内のすべてのfooが対象になります。

たとばfoobarfooの場合/foo/だと先頭のfooのみが対象になりますがgフラグを使うとbarのあとにfooも対象になります。
詳細はMDNを参照して下さい。

lastIndexとは

JavaScriptの正規表現オブジェクトにはlastIndexというプロパティがあり、gまたはyフラグが有効の場合に使われます。
このプロパティはRegexp.exec()が一致する文字列を見つけた場合、その文字列の末尾の位置に設定されます。
一致する文字列が見つからなかった場合は0が設定されます。

冒頭の動画の挙動はこのlastIndexが関係していました。
1回目の検索ではboopを見つけられたのでlatestIndexが4に設定されます。
2回目の検索ではlastIndexの位置から始まるが、対象文字列が見つからないためlastIndexが0に設定されます。
これが繰り返されるといった感じです。

> const r = /boop/g
undefined
> r.lastIndex
0
> r.test("boop")
true
> r.lastIndex
4
> r.test("boop")
false
> r.lastIndex
0
> 

さいごに

JavaScriptなにもわからない。

Discussion