8

Как посчитать количество вхождений строки в строке?

1

Заголовок: Как посчитать количество вхождений строки в другой строке в JavaScript?

Описание проблемы:

Я столкнулся с задачей, в которой мне нужно посчитать, сколько раз конкретная подстрока встречается в другой строке. Например, у меня есть строка "This is a string.", и я хочу получить количество вхождений подстроки "is".

Вот что я пытаюсь реализовать на JavaScript:

var temp = "This is a string.";
alert(temp.count("is")); // ожидается вывод '2'

Однако метод count не является встроенным в JavaScript, и я не знаю, как правильно реализовать подобную функциональность. Можете подсказать, как можно это сделать?

5 ответ(ов)

14

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.

2

Как посчитать количество вхождений подстроки в строку

Если вы хотите подсчитать количество вхождений подстроки в строке, можно использовать следующую функцию на 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

Вы можете найти оригинальный код здесь.

2

Вы можете использовать следующий код для подсчета количества вхождений слова в строке:

function countInstances(string, word) {
   return string.split(word).length - 1;
}
console.log(countInstances("This is a string", "is")); // Выведет 2

Функция countInstances разделяет строку на части, используя указанное слово в качестве разделителя. Метод split возвращает массив, в котором количество элементов на единицу больше, чем количество вхождений слова в строке. Поэтому, чтобы получить количество вхождений, мы просто вычитаем 1 из длины этого массива. Обратите внимание, что данный метод учитывает только полные совпадения искомого слова.

1

Вы можете попробовать следующий код:

var theString = "Это строка.";
console.log(theString.split("строка").length - 1);

Данный код разбивает строку на части по указанному разделителю и возвращает количество вхождений этого разделителя в исходной строке. В примере выше будет подсчитано количество вхождений подстроки "строка" в строке "Это строка."

0

Ваша функция для подсчета вхождений подстроки в строку выглядит хорошо! Давайте я объясню, как она работает.

Вы объявили переменную 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'));

Этот подход универсален и будет работать для любых строк и подстрок, которые вы захотите проверить.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь