Это потому, что с модификатором g
вы получаете все подходящие подстроки, но не соответствующие им группы (то есть, как если бы (...)
пары работали так же, как (?:...)
единицы.
Вы видите. Без модификатора g
:
> 'div.classOneA.classOneB#idOne'.match(/\.([^.#]+)/)
[ '.classOneA',
'classOneA',
index: 3,
input: 'div.classOneA.classOneB#idOne',
groups: undefined ]
С g
модификатором:
> 'div.classOneA.classOneB#idOne'.match(/\.([^.#]+)/g)
[ '.classOneA', '.classOneB' ]
Другими словами: вы получаете все совпадения, но только одно совпадение (0 предметов) для каждого.
Есть много решений:
Используйте LookBehind утверждений, как вы указали сами.
Исправьте каждый результат позже, добавив .map(x=>x.replace(/^\./, ""))
Или, если ваша структура ввода не будет намного более сложной, чем приведенный вами пример, просто используйте более дешевый подход:
> 'div.classOneA.classOneB#idOne'.replace(/#.*/, "").split(".").slice(1)
[ 'classOneA', 'classOneB' ]
Используйте .replace()
+ обратный вызов вместо .match()
, чтобы иметь возможность получить доступ к группам захвата каждого матча:
const str = 'div.classOneA.classOneB#idOne';
const matches = [];
str.replace(/\.([^.#]+)/g, (...args)=>matches.push(args[1]))
console.log(matches); // [ 'classOneA', 'classOneB' ]
Я бы порекомендовал третий (если нет других возможных входов, которые могли бы в итоге его сломать), потому что он гораздо более эффективен (фактические регулярные выражения используются только один раз для обрезки части '#idOne').