いきなり言われてもピンとこないとおもうので、画像を用意しました。
const result = /a(b)?/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", undefined
groups
は名前付きキャプチャを使わなければundefined
なのでいいとして、result[1]
がundefined
ですね。
ただ、このぐらい単純な場合、書き方を変えればそれを回避できます。
const result = /a(b?)/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", ""
この挙動の違いは0文字をキャプチャしたグループとそもそも適用されなかったグループの違いです。
?
や*
、|
によってスキップされてしまったグループをキャプチャすることは当然できません。
その場合、RegExp#exec()
の配列の要素数は変わらず、undefined
が代入されます1。
この挙動はES5時点から変わらず仕様として定められています。
MDN(英語版)にも書いてない挙動2なので、RegExp#exec()
やString#replace(regex, replaceFunction)
でスキップするようなキャプチャグループは記述しないほうが混乱が減るでしょう。
-
英語圏だとブログとかではちらほら記述されているけど、日本語圏では皆無。というか陥りやすい罠なのにMDNに書かれてないのはどうなのか ↩