/** 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 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;}
Usage
occurrences("foofoofoo", "bar"); //0occurrences("foofoofoo", "foo"); //3occurrences("foofoofoo", "foofoo"); //1
allowOverlapping
occurrences("foofoofoo", "foofoo", true); //2
Matches:
foofoofoo1 `----´2 `----´
Unit Test
Benchmark
I've made a benchmark test and my function is more then 10 timesfaster then the regexp match function posted by gumbo. In my teststring is 25 chars length. with 2 occurences of the character 'o'. Iexecuted 1 000 000 times in Safari.
Safari 5.1
Benchmark> Total time execution: 5617 ms (regexp)
Benchmark> Total time execution: 881 ms (my function 6.4x faster)
Firefox 4
Benchmark> Total time execution: 8547 ms (Rexexp)
Benchmark> Total time execution: 634 ms (my function 13.5x faster)
Edit: changes I've made
cached substring length
added type-casting to string.
added optional 'allowOverlapping' parameter
fixed correct output for "" empty substring case.