Как посчитать количество вхождений строки в строке?
Заголовок: Как посчитать количество вхождений строки в другой строке в JavaScript?
Описание проблемы:
Я столкнулся с задачей, в которой мне нужно посчитать, сколько раз конкретная подстрока встречается в другой строке. Например, у меня есть строка "This is a string."
, и я хочу получить количество вхождений подстроки "is"
.
Вот что я пытаюсь реализовать на JavaScript:
var temp = "This is a string.";
alert(temp.count("is")); // ожидается вывод '2'
Однако метод count
не является встроенным в JavaScript, и я не знаю, как правильно реализовать подобную функциональность. Можете подсказать, как можно это сделать?
5 ответ(ов)
g
в регистре регулярного выражения (сокращенно от global) указывает на то, что необходимо искать во всей строке, а не только находить первое вхождение. Это выражение находит is
дважды:
var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Если совпадений нет, то возвращается 0
:
var temp = "Hello World!";
var count = (temp.match(/is/g) || []).length;
console.log(count);
В данном случае, выражение temp.match(/is/g)
возвращает массив всех найденных совпадений. Если совпадений нет, match
вернет null
, поэтому мы используем || []
, чтобы в таком случае получить пустой массив и избежать ошибки при попытке вызвать метод length
у null
.
Как посчитать количество вхождений подстроки в строку
Если вы хотите подсчитать количество вхождений подстроки в строке, можно использовать следующую функцию на JavaScript:
/**
* Функция, которая считает количество вхождений подстроки в строку;
* @param {String} string Исходная строка
* @param {String} subString Подстрока для поиска
* @param {Boolean} [allowOverlapping] Необязательный параметр. (По умолчанию: false)
*
* @author Vitim.us https://gist.github.com/victornpb/7736865
* @see Unit Test https://jsfiddle.net/Victornpb/5axuh96u/
* @see https://stackoverflow.com/a/7924240/938822
*/
function occurrences(string, subString, allowOverlapping) {
string += "";
subString += "";
if (subString.length <= 0) return (string.length + 1);
var n = 0,
pos = 0,
step = allowOverlapping ? 1 : subString.length;
while (true) {
pos = string.indexOf(subString, pos);
if (pos >= 0) {
++n;
pos += step;
} else break;
}
return n;
}
Использование
Вы можете использовать эту функцию следующим образом:
occurrences("foofoofoo", "bar"); // 0
occurrences("foofoofoo", "foo"); // 3
occurrences("foofoofoo", "foofoo"); // 1
Параметр allowOverlapping
Если вам нужно учитывать перекрывающиеся вхождения, вы можете установить параметр allowOverlapping
в true
:
occurrences("foofoofoo", "foofoo", true); // 2
Совпадения:
foofoofoo
1 `----´
2 `----´
Юнит-тест
Вы можете протестировать функцию по следующей ссылке: Проверка на jsFiddle.
Эффективность
Тесты производительности показали, что эта функция работает более чем в 10 раз быстрее, чем функция регулярных выражений, опубликованная пользователем gumbo. В тесте строка длиной 25 символов содержала 2 вхождения символа 'o'. Функция была выполнена 1 000 000 раз в Safari.
Safari 5.1
Benchmark> Общее время выполнения: 5617 мс (regexp)
Benchmark> Общее время выполнения: 881 мс (моя функция 6.4x быстрее)
Firefox 4
Benchmark> Общее время выполнения: 8547 мс (Rexexp)
Benchmark> Общее время выполнения: 634 мс (моя функция 13.5x быстрее)
Изменения
Внесенные изменения:
- Кэширование длины подстроки.
- Добавлено приведение типов к строке.
- Добавлен необязательный параметр
allowOverlapping
. - Исправлен корректный вывод для случая с пустой подстрокой.
Gist
Вы можете найти оригинальный код здесь.
Вы можете использовать следующий код для подсчета количества вхождений слова в строке:
function countInstances(string, word) {
return string.split(word).length - 1;
}
console.log(countInstances("This is a string", "is")); // Выведет 2
Функция countInstances
разделяет строку на части, используя указанное слово в качестве разделителя. Метод split
возвращает массив, в котором количество элементов на единицу больше, чем количество вхождений слова в строке. Поэтому, чтобы получить количество вхождений, мы просто вычитаем 1 из длины этого массива. Обратите внимание, что данный метод учитывает только полные совпадения искомого слова.
Вы можете попробовать следующий код:
var theString = "Это строка.";
console.log(theString.split("строка").length - 1);
Данный код разбивает строку на части по указанному разделителю и возвращает количество вхождений этого разделителя в исходной строке. В примере выше будет подсчитано количество вхождений подстроки "строка" в строке "Это строка."
Ваша функция для подсчета вхождений подстроки в строку выглядит хорошо! Давайте я объясню, как она работает.
Вы объявили переменную temp
, содержащую строку, в которой мы будем искать вхождения. Функция countOccurrences
принимает два аргумента: str
(строка, в которой мы ищем) и value
(значение, которое мы ищем).
Внутри функции вы создаете регулярное выражение regExp
, используя конструктор RegExp
. Опция "gi"
позволяет выполнять поиск без учета регистра и находит все вхождения в строке.
Затем вы используете метод match
для строки str
, который возвращает массив всех совпадений с регулярным выражением. Если совпадений нет, match
возвращает null
, поэтому вы используете логическое ИЛИ (||
) для возвращения пустого массива.
Наконец, вы возвращаете длину массива совпадений, что соответствует количеству вхождений искомой подстроки.
Вот ваш код для удобства:
var temp = "This is a string.";
function countOccurrences(str, value) {
var regExp = new RegExp(value, "gi");
return (str.match(regExp) || []).length;
}
console.log(countOccurrences(temp, 'is'));
Этот подход универсален и будет работать для любых строк и подстрок, которые вы захотите проверить.
Как присвоить многострочную строку переменной?
Преобразование объекта JS в строку JSON
Как преобразовать строку, разделённую запятыми, в массив?
Как заменить символ по заданному индексу в JavaScript?
Удалить первый символ строки, если он равен 0