我需要计算字符串中某个字符出现的次数。

例如,假设我的字符串包含:

var mainStr = "str1,str2,str3,str4";

我想求出逗号的个数,也就是3个字符。以及按逗号分隔后的单个字符串的计数,也就是4。

我还需要验证每个字符串,即str1或str2或str3或str4不应该超过,比如说,15个字符。


当前回答

简单地说,使用分割来找出字符串中某个字符出现的次数。

mainStr.split(" ")。Length //给出4,这是使用分隔符逗号分隔后的字符串数 mainStr.split(" ")。Length - 1 //给出3,这是逗号的计数

其他回答

我对接受的答案做了轻微的改进,它允许检查区分大小写/不区分大小写的匹配,并且是附加到字符串对象的方法:

String.prototype.count = function(lit, cis) {
    var m = this.toString().match(new RegExp(lit, ((cis) ? "gi" : "g")));
    return (m != null) ? m.length : 0;
}

Lit是要搜索的字符串(例如'ex'), cis是不区分大小写的,默认为false,它将允许选择不区分大小写的匹配。 要搜索字符串'I love StackOverflow.com'中的小写字母'o',你可以使用:

var amount_of_os = 'I love StackOverflow.com'.count('o');

Amount_of_os等于2。 如果我们再次使用不区分大小写的匹配来搜索相同的字符串,您将使用:

var amount_of_os = 'I love StackOverflow.com'.count('o', true);

这一次,amount_of_os将等于3,因为字符串中的大写O包含在搜索中。

我发现在非常大的字符串(例如,长度为1 000 000个字符)中搜索字符的最佳方法是使用replace()方法。

window.count_replace = function (str, schar) {
    return str.length - str.replace(RegExp(schar), '').length;
};

您还可以看到另一个JSPerf套件用于测试该方法以及在字符串中查找字符的其他方法。

更新06/10/2022

所以我运行了各种性能测试,如果你的用例允许的话,使用split似乎会表现得最好。


function countChar(char: string, string: string): number  {

  return string.split(char).length - 1

}

countChar('x', 'foo x bar x baz x')


我知道我来晚了,但我很困惑,没有人用最基本的方法来回答这个问题。社区对这个问题提供的大部分答案都是基于迭代的,但都是在每个字符的基础上移动字符串,这并不是真正有效的。

When dealing with a large string that contains thousands of characters walking over each character to get the occurance count can become rather extraneous not to mention a code-smell. The below solutions take advantage of slice, indexOf and the trusted traditional while loop. These approaches prevent us having to walk over each character and will greatly speed up the time it takes to count occurances. These follow similar logic to that you'd find in parsers and lexical analyzers that require string walks.

与Slice一起使用

在这种方法中,我们利用切片和每个indexOf匹配,我们将通过字符串移动我们的方式,并消除之前搜索的药水。每次调用indexOf,它搜索的字符串的大小都会变小。

function countChar (char: string, search: string): number {
  
  let num: number = 0;
  let str: string = search;
  let pos: number = str.indexOf(char);
  
  while(pos > -1) {
    str = str.slice(pos + 1);
    pos = str.indexOf(char);
    num++;
  }

  return num;

}

// Call the function
countChar('x', 'foo x bar x baz x') // 3

使用IndexOf from position

类似于使用slice的第一种方法,但它不是扩大我们正在搜索的字符串,而是利用indexOf方法中的from参数。

function countChar (char: string, str: string): number {
  
  let num: number = 0;
  let pos: number = str.indexOf(char);
  
  while(pos > -1) {
    pos = str.indexOf(char, pos + 1);
    num++;
  }

  return num;

}

// Call the function
countChar('x', 'foo x bar x baz x') // 3

就我个人而言,我倾向于第二种方法而不是第一种,但在处理大字符串和较小尺寸的字符串时,两者都很好且性能良好。

我更新了这个答案。我更喜欢使用火柴的想法,但它更慢:

console.log((“str1,str2,str3,str4”.match(/,/g) ||[]).长度);日志 3 console.log((“str1,str2,str3,str4”.match(new RegExp(“str”, “g”)) ||[]).长度);日志 4

如果事先知道要搜索什么,可以使用正则表达式文字;如果不知道,可以使用RegExp构造函数,并传入g标志作为参数。

匹配结果为空,因此|| []

以下是我在2009年给出的原始答案。它创建了一个不必要的数组,但是使用分割更快(截至2014年9月)。我很矛盾,如果我真的需要速度,毫无疑问我会使用分拆,但我更喜欢使用匹配。

旧答案(2009年):

如果你在找逗号:

(mainStr.split(",").length - 1) //3

如果你在找str

(mainStr.split("str").length - 1) //4

在@Lo的回答和我自己的愚蠢的性能测试中,分裂在速度上领先,至少在Chrome中,但再次创建额外的数组似乎不理智。

该函数以字符串str作为参数,并计算字符串中每个唯一字符的出现次数。结果是每个字符的键值对。

var charFoundMap = {};//object defined
    for (var i = 0; i < str.length; i++) {

       if(!charFoundMap[ str[i] ])  {
        charFoundMap[ str[i] ]=1;
       } 
       else
       charFoundMap[ str[i] ] +=1;
       //if object does not contain this 
    }
    return charFoundMap;

}