Подсчет количества подстроки в строке на JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
const countOccurrences = (text, search) => (text.match(new RegExp(search, 'g')) || []).length;
console.log(countOccurrences('яблоко банан яблоко', 'яблоко')); // Результат: 2
Для определения количества вхождений подстроки search
в строку text
используйте функцию countOccurrences
. Взаимодействие объекта RegExp с глобальным флагом 'g' обеспечивает глобальный поиск. Если совпадений не обнаружено, возвращается 0 благодаря оператору ||, иначе — количество элементов массива, созданного с помощью .match()
.
Анализ метода match и флагов регулярных выражений
Метод .match()
в JavaScript, использующийся совместно с регулярными выражениями, служит мощым инструментом для поиска шаблонов в тексте. Поскольку по умолчанию данный поиск чутко реагирует на разницу в регистрах, он может обеспечивать точный подсчёт в ситуациях, где это критически важно.
Тем не менее, помните, что .match()
в случае отсутствия совпадений возвращает null
. Чтобы избежать ошибки при попытке определить длину null, применяется логический оператор ||
, гарантирующий возврат 0 в случае неудачи поиска.
const caseSensitiveCount = (text, search) => {
// Нашли совпадение! Или не нашли...
const matches = text.match(new RegExp(search, 'g'));
return matches ? matches.length : 0;
};
Альтернатива: подсчет с применением split
Метод .split()
может стать альтернативой .match()
. Этот метод декомпозирует строку на массив, делая это каждый раз при вхождении подстроки. Вычитая единицу из длины полученного массива, мы получаем кол-во вхождений.
const countWithSplit = (text, search) => {
// Делим и властвуем! Кроме случаев, когда разделитель — пустая строка...
if (!search.length) return text.length ? text.length – 1 : 0;
return text.split(search).length – 1;
};
Однако имейте в виду, что при пустой строке search
поведение .split()
становится непредсказуемо: вместо того, чтобы делить по каждому символу, он возвращает массив с исходной строкой, что может привести к неверному результату из-за ошибки на единицу.
Учет перекрывающихся подстрок
С регулярными выражениями часто возникает проблема пропуска перекрывающихся подстрок — они не учтены при стандартном поиске. Но можно избежать этого ограничения, выполнив ручной обход текста.
const countOverlapping = (text, search) => {
// В предвкушении моих итераций, они наблюдают...
// Избежать бесконечных циклов поможет переход через текст на должное расстояние
let count = 0, position = 0, step = search.length > 0 ? search.length : 1;
while ((position = text.indexOf(search, position)) !== -1) {
count++;
position += step;
}
return count;
};
Эта функция успешно справляется с подсчётом даже пустых строк, избегает бесконечных циклов и гарантирует точность подсчёта.
Следите за производительностью
Кэширование длины строки search
способно заметно повысить производительность. Это особо актуально, когда работа происходит с большими объёмами текста: запоминая это значение, можно избежать вычисления на каждой итерации.
Тесты производительности показали, что некоторые методы опережают поиск основанный на регулярных выражениях:
- Использование
.indexOf()
в связке с циклами для простых шаблонов значительно эффективнее. - Кэширование размеров
text
иsearch
ускоряет методы, не зависимые от этих параметров. - Где это возможно, рекомендуется применять метод
split()
, так как его повсеместное использование на длинных строках может снизить производительность.
Визуализация
Попробуйте визуализировать это с помощью предметов из реального мира. Пусть вас просят подсчитать вхождения слова:
Исходная строка: "🍎🍌🍎🍎🍌🍎"
Подстрока для подсчета: "🍎"
Мы представляем себе ситуацию, когда считаем количество яблок "🍎" в корзине, полной фруктов. Каждый символ "🍎" обозначает искомый элемент.
Полезные материалы
- String.prototype.match() – JavaScript | MDN – Инструкция по использованию
.match()
на MDN. - JavaScript: How many times a character occurs in a string? – Stack Overflow – Ответы пользователям с практическими примерами на Stack Overflow.
- JavaScript RegExp Object – Работа с регулярными выражениями в JavaScript – Полное руководство по регулярным выражениям в JavaScript.
- JavaScript String search() Method – Обучающий материал W3Schools об использовании метода
.search()
. - Строки – Ответы на вопросы о работе со строками в JavaScript на портале JavaScript.info.
- ECMAScript 2015 Language Specification – ECMA-262 6th Edition – Официальная спецификация языка ECMAScript, содержащая детали о методах работы со строками в JavaScript.