gオプションを使った正規表現で、グループごとのキャプチャ文字列を取り出したい

投稿者: Anonymous

キャプチャグループを含む正規表現を String.prototype.match() に渡すと、戻り値の配列から各グループのキャプチャ文字列を取り出せます。

console.log("a123b456".match(/(d+)|(.+?)/));
// => ["a", undefined, "a"]

一方gオプションを付けると、各マッチ回のマッチ文字列全体しか入っていないようです。

console.log("a123b456".match(/(d+)|(.+?)/g));
// => ["a", "123", "b", "456"]

Rubyでいう次のコードのように、キャプチャグループも個別に取得する方法はありますか?

p "a123b456".scan(/(d+)|(.+?)/)
# => [[nil, "a"], ["123", nil], [nil, "b"], ["456", nil]]

解決

キャプチャ文字列を取り出したい時は Regexp.prototype.exec() を使います。

ただし一回の呼び出しでは一回分のマッチ結果しか返さない*1ので、全件を取得したい場合は繰り返し呼び出す必要があります。
*1: 要はgオプションのない正規表現を String.prototype.match() に渡した時と同じ配列が返ってくる

_x000D_

_x000D_

var re=/(d+)|(.+?)/g;_x000D_
var str = "a123b456";_x000D_
var result;_x000D_
while ((result = re.exec(str)) !== null) {_x000D_
 console.log(JSON.stringify(result));_x000D_
}

_x000D_

_x000D_

_x000D_

で、これを使ってRubyの String#scan を再現すると、例えば次のようになります。

_x000D_

_x000D_

String.prototype.scan = function(re) {_x000D_
  var m, r = [];_x000D_
  while ((m = re.exec(this)) !== null) {_x000D_
    r.push(m.slice(1)); // sliceで[0]を取り除く_x000D_
  }_x000D_
  return r;_x000D_
};_x000D_
console.log(JSON.stringify("a123b456".scan(/(d+)|(.+?)/g)));

_x000D_

_x000D_

_x000D_

参考 JavaScript equivalent of Ruby’s String#scan – Stack Overflow

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *