web-dev-qa-db-ja.com

Javascript:RegEx .exec結果で複数の一致を取得する方法

私が走るとき

/(a)/g.exec('a a a ').length

私は得る

2

しかし、それは戻るべきだと思いました

3

文字列には2ではなく3のasがあるためです!

何故ですか?

RegExで文字列のすべての出現を検索し、それらを繰り返し処理できるようにしたいと考えています。

FWIW:私はnode.jsを使用しています

26
Trindaz

exec()は、最初の一致のキャプチャのセットのみを返し、期待どおりの一致のセットは返していません。したがって、実際に表示されているのは_$0_(完全一致、 "a")と_$1_(最初のキャプチャ)です。長さ2の配列。exec()は、againを呼び出して、nextが一致します。 From [〜#〜] mdn [〜#〜]

正規表現で「g」フラグを使用している場合は、execメソッドを複数回使用して、同じ文字列で連続する一致を見つけることができます。これを行うと、正規表現のlastIndexプロパティで指定されたstrの部分文字列から検索が開始されます(テストによってlastIndexプロパティも進みます)。

35
Andrew Cheong

代わりにmatchを使用できます:

'a a a'.match(/(a)/g).length  // outputs: 3
24
mVChr

あなたは最初のaにのみ一致しています。長さが2である理由は、最初の一致と、最初の一致の括弧で囲まれたグループ部分を見つけるためです。あなたの場合、それらは同じです。

この例を考えてみましょう。

var a = /b(a)/g.exec('ba ba ba ');
alert(a);

ba, aを出力します。配列の長さは2のままですが、何が起こっているかはより明白です。 「ba」は完全一致です。 aは、括弧で囲まれた最初のグループ化一致です。

MDNドキュメント はこれをサポートします-最初の一致と含まれているグループのみが返されます。すべての一致を見つけるには、mVChrで述べられているようにmatch()を使用します。

7
Jeanne Boyarsky

コード:

alert('a a a'.match(/(a)/g).length);

出力:

3
4
Ωmega

while loopが役立ちます

x = 'a a a a';
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // ouput: "a"
}

カウンターを追加すると、その長さが得られます。

x = 'a a a a';
counter = 0;
y = new RegExp(/a/g);
while(null != (z=y.exec(x))) {
   console.log(z);     // output: object
   console.log(z[0]);  // output: "a"
   counter++;
}
console.log(counter);  // output: 4

これは非常に安全です。一致が見つからなくても、終了してカウンタは0になります。

主な目的は、RegExpを使用して、同じ一致するRegExpの文字列からすべての値をループして取得する方法を伝えることです。

4
ajaykools

regexp.exec(str)は、他の回答で言及されているように、最初の一致または完全一致と最初のキャプチャ(re = /(a)/g;の場合)を返します

const str = 'a a a a a a a a a a a a a';
const re = /a/g;

const result = re.exec(str);
console.log(result);

しかし、それも覚えているregexp.lastIndexプロパティでのその後の位置です。

次の呼び出しはregexp.lastIndexから検索を開始し、次の一致を返します。

一致するものがもうない場合、regexp.execはnullを返し、regexp.lastIndexは0に設定されます。

const str = 'a a a';
const re = /a/g;

const a = re.exec(str);
console.log('match : ', a, ' found at : ', re.lastIndex);

const b = re.exec(str);
console.log('match : ', b, ' found at : ', re.lastIndex);

const c = re.exec(str);
console.log('match : ', c, ' found at : ', re.lastIndex);

const d = re.exec(str);
console.log('match : ', d, ' found at : ', re.lastIndex);

const e = re.exec(str);
console.log('match : ', e, ' found at : ', re.lastIndex);

そのため、一致がnullになると停止するwhileループを使用できます。

const str = 'a a a';
const re = /a/g;

while(match = re.exec(str)){
  console.log(match, ' found at : ', match.index); 
}
1
Taki