93

私はJavaScriptのこの行を期待します:

"foo bar baz".match(/^(\s*\w+)+$/)

次のようなものを返すには:

["foo bar baz", "foo", " bar", " baz"]

ただし、代わりに、最後にキャプチャされた一致のみが返されます。

["foo bar baz", " baz"]

キャプチャされたすべての一致を取得する方法はありますか?

4

5 に答える 5

97

キャプチャグループを繰り返すと、ほとんどのフレーバーで、最後のキャプチャのみが保持されます。以前のキャプチャは上書きされます。.NETなどの一部のフレーバーでは、すべての中間キャプチャを取得できますが、Javascriptの場合はそうではありません。

つまり、Javascriptでは、キャプチャグループがN個あるパターンがある場合、それらのグループの一部が繰り返されていても、一致ごとに正確にN個の文字列しかキャプチャできません。

したがって、一般的に言えば、何をする必要があるかに応じて、次のようになります。

  • オプションの場合は、代わりに区切り文字で分割します
  • 一致する代わりに、おそらくループ で/(pattern)+/一致する/pattern/gexec
    • これら2つは完全に同等ではないことに注意してください、しかしそれはオプションかもしれません
  • マルチレベルマッチングを実行します。
    • 1回の試合で繰り返されるグループをキャプチャする
    • 次に、別の正規表現を実行して、その一致を分解します

参考文献


<some;words;here>これは、テキストを照合し、execループを使用し、次に分割し;て個々の単語を取得する例です(ideone.comも参照)。

var text = "a;b;<c;d;e;f>;g;h;i;<no no no>;j;k;<xx;yy;zz>";

var r = /<(\w+(;\w+)*)>/g;

var match;
while ((match = r.exec(text)) != null) {
  print(match[1].split(";"));
}
// c,d,e,f
// xx,yy,zz

使用されるパターンは次のとおりです。

      _2__
     /    \
<(\w+(;\w+)*)>
 \__________/
      1

これは、、、などに一致<word><word;another>ます<word;another;please>。グループ2は、任意の数の単語をキャプチャするために繰り返されますが、最後のキャプチャのみを保持できます。単語のリスト全体がグループ1によってキャプチャされます。この文字列はsplitセミコロン区切り文字になります。

関連する質問

于 2010-08-21T14:24:13.090 に答える
7

これはどうですか?"foo bar baz".match(/(\w+)+/g)

于 2010-08-21T14:10:34.480 に答える
6

文字列を分割する方法についてより複雑な要件がない限り、文字列を分割してから、最初の文字列を返すことができます。

var data = "foo bar baz";
var pieces = data.split(' ');
pieces.unshift(data);
于 2010-08-21T14:22:30.333 に答える
4

'g'を使用してみてください:

"foo bar baz".match(/\w+/g)
于 2010-08-21T15:41:10.703 に答える
0

LAZY評価を使用できます。したがって、*(GREEDY)を使用する代わりに、?を使用してみてください (怠惰)

正規表現:(\ s * \ w +)?

結果:

一致1:foo

マッチ2:バー

マッチ3:バズ

于 2021-09-28T10:53:56.180 に答える