7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RegExp#exec() が返す配列にはundefinedが含まれているかもしれない

Last updated at Posted at 2019-05-14

いきなり言われてもピンとこないとおもうので、画像を用意しました。

const result = /a(b)?/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", undefined

testRegex.png
groupsは名前付きキャプチャを使わなければundefinedなのでいいとして、result[1]undefinedですね。
ただ、このぐらい単純な場合、書き方を変えればそれを回避できます。

const result = /a(b?)/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", ""

testRegex2.png
この挙動の違いは0文字をキャプチャしたグループそもそも適用されなかったグループの違いです。
?*|によってスキップされてしまったグループをキャプチャすることは当然できません。
その場合、RegExp#exec()の配列の要素数は変わらず、undefinedが代入されます1

この挙動はES5時点から変わらず仕様として定められています

MDN(英語版)にも書いてない挙動2なので、RegExp#exec()String#replace(regex, replaceFunction)でスキップするようなキャプチャグループは記述しないほうが混乱が減るでしょう。

  1. ただし非常に古い一部のブラウザ(IE含)はundefinedではなく""になってしまっています

  2. 英語圏だとブログとかではちらほら記述されているけど、日本語圏では皆無。というか陥りやすい罠なのにMDNに書かれてないのはどうなのか

7
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?