Как захватить произвольное количество групп в JavaScript Regexp?

Я бы ожидал эту строку JavaScript:

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

чтобы вернуть что-то вроде:

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

но вместо этого он возвращает только последнее зафиксированное совпадение:

["foo bar baz", " baz"]

Есть ли способ получить все захваченные совпадения?

Ответ 1

Когда вы повторяете группу захвата, в большинстве вкусов сохраняется только последний захват; любой предыдущий захват перезаписывается. В некотором аромате, например.NET, вы можете получить все промежуточные захваты, но это не относится к Javascript.

То есть, в Javascript, если у вас есть шаблон с N группами захвата, вы можете захватывать ровно N строк за матч, даже если некоторые из этих групп были повторены.

Итак, в общем, в зависимости от того, что вам нужно сделать:

  • Если это вариант, разделите на разделителя вместо
  • Вместо сопоставления /(pattern)+/, возможно, match /pattern/g, возможно, в цикле exec
    • Обратите внимание, что эти два не совсем эквивалентны, но это может быть вариант
  • Многоуровневое соответствие:
    • Захват повторяющейся группы в одном матче
    • Затем запустите другое регулярное выражение, чтобы разбить это совпадение

Рекомендации


пример

Здесь приведен пример соответствия <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 на разделитель с запятой.

Связанные вопросы

Ответ 2

Как насчет этого? "foo bar baz".match(/(\w+)+/g)

Ответ 3

Если у вас нет более сложного требования о том, как вы разбиваете свои строки, вы можете разбить их, а затем вернуть им исходную строку:

var data = "foo bar baz";
var pieces = data.split(' ');
pieces.unshift(data);

Ответ 4

попробуйте использовать 'g':

"foo bar baz".match(/\w+/g)