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

Javascript: как получить несколько совпадений в результатах RegEx.exec

Когда я запустил

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

Я получаю

2

но я думал, что он должен вернуться

3

потому что в строке есть 3 a, а не 2!

Почему это?

Я хочу, чтобы иметь возможность искать все строки строки в RegEx и перебирать их.

FWIW: Я использую node.js

4b9b3361

Ответ 1

exec() возвращает только набор захватов для первого совпадения, а не набор совпадений, как вы ожидаете. Итак, вы действительно видите $0 (весь матч, "a" ) и $1 (первый захват) - т.е. массив длиной 2. exec(), тем временем, разработан таким образом, что вы можете снова вызвать его, чтобы получить захваты для следующего совпадения. Из MDN:

Если ваше регулярное выражение использует флаг "g", вы можете использовать метод exec несколько раз, чтобы найти последовательные совпадения в одной строке. Когда вы это сделаете, поиск начинается с подстроки str, заданной с помощью свойства регулярного выражения lastIndex (тест также увеличивает свойство lastIndex).

Ответ 2

Вместо match можно использовать

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

Ответ 3

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

Рассмотрим этот пример.

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

Он выводит ba, a. Длина массива по-прежнему равна 2, но более очевидно, что происходит. "ba" - полный матч. a - это первое совпадение с совпадающими именами.

документация MDN поддерживает это - возвращается только первое совпадение и содержащиеся группы. Чтобы найти все совпадения, вы должны использовать match(), как указано в mVChr.

Ответ 4

Код:

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

Вывод:

3