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

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

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

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

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


当前回答

下面使用正则表达式测试长度。Testex确保不存在16个或更多的连续非逗号字符。如果它通过了测试,那么它将继续拆分字符串。计算逗号的数量就像计算符号减1一样简单。

var mainStr = "str1,str2,str3,str4";
var testregex = /([^,]{16,})/g;
if (testregex.test(mainStr)) {
  alert("values must be separated by commas and each may not exceed 15 characters");
} else {
  var strs = mainStr.split(',');
  alert("mainStr contains " + strs.length + " substrings separated by commas.");
  alert("mainStr contains " + (strs.length-1) + " commas.");
}

其他回答

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

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, char) } 对于(var c = 0, i = 0, len = str.length;我< len;+ + i) } if (str[i] == char) } c + +; } } return c; } console.log(charOccurances('example/path/script.js', '/'));/ / 2

或者作为原型函数:

String.prototype.charOccurances =函数(char) } 对于(var c = 0, i = 0, len = this.length;我< len;+ + i) } if (this[i] == char) } c + +; } } return c; } console.log('example/path/script.js'. charoccurances ('/'));/ / 2

这里有一个和split()和replace方法一样快的方法,它们比regex方法快一点点(在Chrome和Firefox中都是如此)。

let num = 0;
let str = "str1,str2,str3,str4";
//Note: Pre-calculating `.length` is an optimization;
//otherwise, it recalculates it every loop iteration.
let len = str.length;
//Note: Don't use a `for (... of ...)` loop, it's slow!
for (let charIndex = 0; charIndex < len; ++charIndex) {
  if (str[charIndex] === ',') {
    ++num;
  }
}

var mainStr = “str1,str2,str3,str4”; var splitStr = mainStr.split(“,”).length - 1;减去 1 很重要! alert(splitStr);

分割成一个数组会给我们一些元素,这些元素总是比字符的实例数多1。这可能不是最有效的内存,但如果您的输入总是很小,这是一种直接且易于理解的方法。

如果您需要解析非常大的字符串(大于几百个字符),或者如果这是在处理大量数据的核心循环中,我会推荐不同的策略。

我刚刚在repl上做了一个快速而肮脏的测试。它使用Node v7.4。对于单个字符,标准的For循环是最快的:

一些代码:

// winner!
function charCount1(s, c) {
    let count = 0;
    c = c.charAt(0); // we save some time here
    for(let i = 0; i < s.length; ++i) {
        if(c === s.charAt(i)) {
            ++count;
        }
    }
    return count;
}

function charCount2(s, c) {
    return (s.match(new RegExp(c[0], 'g')) || []).length;
}

function charCount3(s, c) {
    let count = 0;
    for(ch of s) {
        if(c === ch) {
            ++count;
        }
    }
    return count;
}

function perfIt() {
    const s = 'Hello, World!';
    const c = 'o';

    console.time('charCount1');
    for(let i = 0; i < 10000; i++) {
        charCount1(s, c);
    }
    console.timeEnd('charCount1');
    
    console.time('charCount2');
    for(let i = 0; i < 10000; i++) {
        charCount2(s, c);
    }
    console.timeEnd('charCount2');
    
    console.time('charCount3');
    for(let i = 0; i < 10000; i++) {
        charCount2(s, c);
    }
    console.timeEnd('charCount3');
}

几次运行的结果:

perfIt()
charCount1: 3.301ms
charCount2: 11.652ms
charCount3: 174.043ms
undefined

perfIt()
charCount1: 2.110ms
charCount2: 11.931ms
charCount3: 177.743ms
undefined

perfIt()
charCount1: 2.074ms
charCount2: 11.738ms
charCount3: 152.611ms
undefined

perfIt()
charCount1: 2.076ms
charCount2: 11.685ms
charCount3: 154.757ms
undefined

更新2021年2月10日:修复了repl中的拼写错误。它演示

更新2020年10月24日:Node.js 12仍然是这样(你自己在这里玩)