Как посчитать вхождение строки в строку? - PullRequest
514 голосов
/ 24 октября 2010

Как подсчитать, сколько раз конкретная строка встречается в другой строке. Например, это то, что я пытаюсь сделать в Javascript:

var temp = "This is a string.";
alert(temp.count("is")); //should output '2'

Ответы [ 28 ]

883 голосов
/ 24 октября 2010

В регулярном выражении 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);
216 голосов
/ 28 октября 2011
/** Function that count occurrences of a substring in a string;
 * @param {String} string               The string
 * @param {String} subString            The sub string to search for
 * @param {Boolean} [allowOverlapping]  Optional. (Default:false)
 *
 * @author Vitim.us https://gist.github.com/victornpb/7736865
 * @see Unit Test https://jsfiddle.net/Victornpb/5axuh96u/
 * @see /2466857/kak-poschitat-vhozhdenie-stroki-v-stroku
 */
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

occurrences("foofoofoo", "foofoo", true); //2

Матчи:

  foofoofoo
1 `----´
2    `----´

Модульный тест

Benchmark

Я сделал тест производительности, и моя функция более чем в 10 раз быстрее, чем функция соответствия регулярному выражению, опубликованная gumbo. В моем тесте строка длиной 25 символов. с 2 вхождениями персонажа «о». я выполнено 1 000 000 раз в Safari.

Safari 5.1

Тест> Общее время выполнения: 5617 мс (регулярное выражение)

Тест> Общее время выполнения: 881 мс (моя функция в 6,4 раза быстрее)

Firefox 4

Тест> Общее время выполнения: 8547 мс (Rexexp)

Тест> Общее время выполнения: 634 мс (моя функция в 13,5 раз быстрее)


Редактировать: изменения, которые я сделал

  • длина кешированной подстроки

  • добавлено приведение типов к строке.

  • добавлен необязательный параметр allowOverlapping

  • исправлен правильный вывод для "" пустого подстроки.

Суть
95 голосов
/ 24 октября 2010
function countInstances(string, word) {
   return string.split(word).length - 1;
}
76 голосов
/ 24 февраля 2013

Вы можете попробовать это:

var theString = "This is a string.";
console.log(theString.split("is").length - 1);
32 голосов
/ 09 апреля 2013

Мое решение:

var temp = "This is a string.";

function countOcurrences(str, value) {
  var regExp = new RegExp(value, "gi");
  return (str.match(regExp) || []).length;
}

console.log(countOcurrences(temp, 'is'));
18 голосов
/ 24 октября 2010

Вы можете использовать match для определения такой функции:

String.prototype.count = function(search) {
    var m = this.match(new RegExp(search.toString().replace(/(?=[.\\+*?[^\]$(){}\|])/g, "\\"), "g"));
    return m ? m.length:0;
}
10 голосов
/ 15 марта 2014

Версия без регулярных выражений:

 var string = 'This is a string',
    searchFor = 'is',
    count = 0,
    pos = string.indexOf(searchFor);

while (pos > -1) {
    ++count;
    pos = string.indexOf(searchFor, ++pos);
}

console.log(count);   // 2
9 голосов
/ 13 августа 2011

Просто код-гольф Ребекка Чернофф х решение : -)

alert(("This is a string.".match(/is/g) || []).length);
8 голосов
/ 29 августа 2013

Вот самая быстрая функция!

Почему она быстрее?

  • Не проверяет char по char (с 1 исключением)
  • Использует некоторое времяи увеличивает на 1 переменную (число символов в переменной) по сравнению с циклом for, проверяющим длину и увеличивающим на 2 переменные (обычно это переменная i и переменная с количеством символов)
  • использует WAY меньше переменных
  • Не использует регулярное выражение!
  • Использует (надеюсь) высокооптимизированную функцию
  • Все операции объединены настолько, насколько это возможно, избегая замедлений из-за нескольких операций

    String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
    

Вот более медленная и более читаемая версия:

    String.prototype.timesCharExist = function ( chr ) {
        var total = 0, last_location = 0, single_char = ( chr + '' )[0];
        while( last_location = this.indexOf( single_char, last_location ) + 1 )
        {
            total = total + 1;
        }
        return total;
    };

Эта медленнее из-за счетчика, длинных имен переменных и неправильного использования 1 переменной.

Чтобы использовать его, вы просто делаете это:

    'The char "a" only shows up twice'.timesCharExist('a');

Редактировать: (2013/12/16)

НЕ использовать с Opera 12.16 или старше!это займет почти в 2,5 раза больше, чем решение для регулярных выражений!

В Chrome это решение займет от 14 мс до 20 мс для 1000000 символов.

Решение для регулярных выражений займет 11-14 мс на ту же сумму.

Использование функции (за пределами String.prototype) займет около 10-13 мс.

Вот код, используемый:

    String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};

    var x=Array(100001).join('1234567890');

    console.time('proto');x.timesCharExist('1');console.timeEnd('proto');

    console.time('regex');x.match(/1/g).length;console.timeEnd('regex');

    var timesCharExist=function(x,c){var t=0,l=0,c=(c+'')[0];while(l=x.indexOf(c,l)+1)++t;return t;};

    console.time('func');timesCharExist(x,'1');console.timeEnd('func');

Результат всех решенийдолжно быть 100 000!

Примечание: если вы хотите, чтобы эта функция считала более 1 символа, измените значение c=(c+'')[0] на c=c+''

8 голосов
/ 10 сентября 2016

String.prototype.Count = function (find) {
    return this.split(find).length - 1;
}

console.log("This is a string.".Count("is"));

Это вернет 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...