Подтвердить что ты не робот

Итератор регулярного выражения JavaScript для извлечения групп

скажем, мы имеем следующий текст: "1 a, 2 b, 3 c, 4 d" и следующее выражение:/\ d (\ w)/g

то, что мы хотим сделать, - извлечь a, b, c, d, как это обозначено регулярным выражением.

К сожалению, "1 a, 2 b, 3 c, 4 d".match(/\ d (\ w)/g) создаст массив: 1 a, 2 b, 3 c, 4 d и RegExp. будет содержать только группы из последнего совпадения, то есть RegExp. $1 == 'd'.

как я могу перебирать это регулярное выражение, чтобы я мог также извлекать группы... Я ищу решение, которое также эффективно с точки зрения памяти, т.е. какой-то объект итератора

EDIT: Он должен быть общим. Я просто представляю простой пример. Одним из решений является цикл над массивом и повторное применение регулярного выражения для каждого элемента без глобального флага, но я считаю это решение немного глупым, хотя кажется, что это единственный способ сделать это.

4b9b3361

Ответ 1

var myregexp = /\d (\w)/g;
var match = myregexp.exec(subject);
while (match != null) {
    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
    match = myregexp.exec(subject);
}

(бесстыдно взято из RegexBuddy)

Ответ 2

Более короткое, более простое (хотя и менее эффективное) решение заключается в использовании String.prototype.replace. replace уникальна тем, что она неявно выполняет итерацию по всем совпадениям и выполняет функцию для каждого совпадения. Конечно, вы можете использовать эту функцию для фактической замены текста, но, несмотря на то, что имя функции действительно не требуется:

"1 a,2 b,3 c,4 d".replace(/\d (\w)/g, function(complete_match, matched_letter) {
    console.log(matched_letter);
});

Это будет вести журнал a, b, c, затем d на консоли. (Также будет возвращено "undefined,undefined,undefined,undefined", но здесь нас это не волнует.)

В общем случае аргумент функции для замены вызывается со следующими параметрами:

function(match, p1, p2, [...], offset, string)
  • match - соответствующая подстрока.
  • p1 и т.д. - это совпадающие захваченные группы, если они есть. Группы находятся в порядке открывающей скобки, которой они соответствуют (то есть левый первый, первый внешний). Если группа соответствует нескольким подстрокам (т.е. В сценарии (.)+), захватывается только последняя (самая правая) подстрока.
  • offset - это индекс в исходной строке этого совпадения
  • string - это строка, на которой был вызван replace.

Ручная итерация, скорее всего, более эффективна, но этот метод не медленный, и он короче и (IMHO) легче читать; Я склонен использовать этот шаблон в ручном цикле.

Ответ 3

Это будет работать:

"1 a,2 b,3 c,4 d".match(/\w(?:,|$)/g).join(' '); // => "a, b, c, d"

Если вам нужна итерация:

var r = /\d (\w)/g,
    s = "1 a,2 b,3 c,4 d",
    m;

while ( m = r.exec(s) ) {
    // `m` is your match, `m[1]` is the letter
}