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


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

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

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

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

но вместо этого он возвращает только снятое матч:

["foo bar baz", " baz"]

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

4 67

4 ответа:

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

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

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

  • если это опция, разделите на разделители вместо
  • вместо сопоставления /(pattern)+/, может соответствовать /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 на запятой.

вопросы

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

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

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

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

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