Javascript: как получить несколько совпадений в результатах RegEx.exec
Когда я запустил
/(a)/g.exec('a a a ').length
Я получаю
2
но я думал, что он должен вернуться
3
потому что в строке есть 3 a
, а не 2!
Почему это?
Я хочу, чтобы иметь возможность искать все строки строки в RegEx и перебирать их.
FWIW: Я использую node.js
Ответы
Ответ 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