Help us understand the problem. What is going on with this article?

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

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

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に書かれてないのはどうなのか 

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away