Javascript 如何计算字符串中字符串的出现次数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4009756/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 07:07:30  来源:igfitidea点击:

How to count string occurrence in string?

javascriptregexstring

提问by TruMan1

How can I count the number of times a particular string occurs in another string. For example, this is what I am trying to do in Javascript:

如何计算特定字符串在另一个字符串中出现的次数。例如,这就是我在 Javascript 中尝试做的事情:

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

回答by Rebecca Chernoff

The gin the regular expression (short for global) says to search the whole string rather than just find the first occurrence. This matches istwice:

g正则表达式(简称全球)说,搜索整个字符串,而不是只要找到第一次出现。这匹配is两次:

var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);

And, if there are no matches, it returns 0:

并且,如果没有匹配项,则返回0

var temp = "Hello World!";
var count = (temp.match(/is/g) || []).length;
console.log(count);

回答by Vitim.us

/** 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 http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string/7924240#7924240
 */
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"); //0

occurrences("foofoofoo", "foo"); //3

occurrences("foofoofoo", "foofoo"); //1

allowOverlapping

允许重叠

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

Matches:

火柴:

  foofoofoo
1 `----′
2    `----′

Unit Test

单元测试

Benchmark

基准

I've made a benchmark test and my function is more then 10 times faster then the regexp match function posted by gumbo. In my test string is 25 chars length. with 2 occurences of the character 'o'. I executed 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.

我做了一个基准测试,我的函数比 gumbo 发布的正则表达式匹配函数快 10 倍以上。在我的测试字符串中,长度为 25 个字符。字符 'o' 出现 2 次。我在 Safari 中执行了 1 000 000 次。

Safari 5.1

Benchmark> 总执行时间:5617 ms (regexp)

基准> 总执行时间:881 毫秒(我的函数快 6.4 倍)

火狐 4

Benchmark> 总执行时间:8547 ms (Rexexp)

基准> 总执行时间:634 毫秒(我的函数快了 13.5 倍)


编辑:我所做的更改

  • 缓存子串长度

  • 向字符串添加了类型转换。

  • 添加了可选的“allowOverlapping”参数

  • 修复了 "" 空子字符串情况的正确输出。

要旨

回答by Orbit

function countInstances(string, word) {
   return string.split(word).length - 1;
}

回答by Freezy Ize

You can try this:

你可以试试这个:

var theString = "This is a string.";
console.log(theString.split("is").length - 1);

回答by Gere

My solution:

我的解决方案:

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'));

回答by Gumbo

You can use matchto define such function:

您可以使用match来定义这样的函数:

String.prototype.count = function(search) {
    var m = this.match(new RegExp(search.toString().replace(/(?=[.\+*?[^\]$(){}\|])/g, "\"), "g"));
    return m ? m.length:0;
}

回答by Faraz Kelhini

The non-regex version:

非正则表达式版本:

 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

回答by TMS

Just code-golfing Rebecca Chernoff's solution:-)

只是打高尔夫球Rebecca Chernoff解决方案:-)

alert(("This is a string.".match(/is/g) || []).length);

回答by Fad Seck

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

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

This will return 2.

这将返回 2。

回答by Ismael Miguel

Here is the fastest function!

这里是最快的功能!

Why is it faster?

为什么它更快?

  • Doesn't check char by char (with 1 exception)
  • Uses a while and increments 1 var (the char count var) vs. a for loop checking the length and incrementing 2 vars (usually var i and a var with the char count)
  • Uses WAY less vars
  • Doesn't use regex!
  • Uses an (hopefully) highly optimized function
  • All operations are as combined as they can be, avoiding slowdowns due to multiple operations

    String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
    
  • 不按字符检查字符(有 1 个例外)
  • 使用一段时间并增加 1 个变量(字符计数变量)与检查长度并增加 2 个变量的 for 循环(通常是变量 i 和带有字符计数的变量)
  • 使用更少的变量
  • 不使用正则表达式!
  • 使用(希望)高度优化的功能
  • 所有操作尽可能组合在一起,避免因多次操作而导致速度减慢

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

Here is a slower and more readable version:

这是一个更慢且更易读的版本:

    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;
    };

This one is slower because of the counter, long var names and misuse of 1 var.

由于计数器、长 var 名称和滥用 1 var,这个速度较慢。

To use it, you simply do this:

要使用它,您只需执行以下操作:

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

Edit: (2013/12/16)

编辑:(2013/12/16)

DON'T use with Opera 12.16 or older! it will take almost 2.5x more than the regex solution!

不要与 Opera 12.16 或更高版本一起使用!它将比正则表达式解决方案多花近 2.5 倍的时间!

On chrome, this solution will take between 14ms and 20ms for 1,000,000 characters.

在 chrome 上,对于 1,000,000 个字符,此解决方案将花费 14 到 20 毫秒。

The regex solution takes 11-14ms for the same amount.

对于相同的数量,正则表达式解决方案需要 11-14 毫秒。

Using a function (outside String.prototype) will take about 10-13ms.

使用函数(外部String.prototype)大约需要 10-13 毫秒。

Here is the code used:

这是使用的代码:

    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');

The result of all the solutions should be 100,000!

所有解的结果应该是100,000!

Note: if you want this function to count more than 1 char, change where is c=(c+'')[0]into c=c+''

注意:如果您希望此函数计数超过 1 个字符,请将 where 更改c=(c+'')[0]c=c+''