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

IT技术 javascript regex string
2021-01-18 10:40:13

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

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

g正则表达式(简称全球)说,搜索整个字符串,而不是只要找到第一次出现。这匹配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);

现代而优雅,但 Vitimtk 的解决方案效率更高。大家觉得他的代码怎么样?
2021-03-12 10:40:13
这最好地回答了这个问题。如果有人问“在特殊情况下(没有正则表达式),我怎样才能将这个速度提高 10 倍”,那么 Vitimtk 会赢得这个问题。
2021-03-14 10:40:13
谢谢你..count = (str.match(/is/g) || []).length如果你没有比赛,我会去处理。
2021-03-14 10:40:13
马特的答案应该在答案中!
2021-03-17 10:40:13
我不认为这个答案与问题正确匹配,因为它不像用例描述的那样将字符串作为要匹配的参数。当然,您可以使用RegExp构造函数动态创建正则表达式并传递您要查找的字符串,但在这种情况下,您必须转义所有元字符。在这种情况下,最好使用纯字符串方法。
2021-04-06 10:40:13
/** 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;
}

用法

occurrences("foofoofoo", "bar"); //0

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

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

允许重叠

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

火柴:

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

单元测试

基准

我做了一个基准测试,我的函数比 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”参数

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

要旨
我在这里找到了您的代码:success-equation.com/mind_reader.html真的很好,程序员介意在那里放一个参考。
2021-03-12 10:40:13
+1,但是您substring.length几乎正在检查每个循环,您应该考虑将其缓存在while
2021-03-20 10:40:13
@ajax333221 天​​哪,你读懂了我的想法,几天前我做了这个改进,我打算编辑我​​的答案jsperf.com/count-string-occurrence-in-string
2021-03-30 10:40:13
我在 Safari 5 中重复了这个测试,并用一个小 (100b) 的字符串得到了类似的结果,但用一个更大的字符串 (16kb),正则表达式对我来说运行得更快。对于一次迭代(不是 1,000,000),无论如何差异都小于一毫秒,所以我投票给了正则表达式。
2021-03-31 10:40:13
@DanielZuzevich 它将类型强制为String,以防万一occurrences(11,1) //2它仍然有效。(这样做比检查类型和调用toString()更快
2021-04-04 10:40:13

function countInstances(string, word) {
   return string.split(word).length - 1;
}
console.log(countInstances("This is a string", "is"))

@Antal - 看起来像之前的 chrome 测试版中的一个错误,更新到最新版本后可以工作,不过我仍然会避开这种方法。
2021-03-18 10:40:13
@NickCraver 出于好奇,你为什么要避开这种方法?(除了您的 Beta 浏览器中的错误)
2021-03-30 10:40:13
这对我来说似乎是一个完全有效的解决方案。
2021-04-06 10:40:13
@JonnyLin 它会创建不必要的分配,当替代方案没有时,您会立即丢弃 - 可能非常大,具体取决于数据。
2021-04-09 10:40:13
这是一种非常消耗内存的方法,效率不高,并且会在有太多数据需要处理的情况下产生很大的内存压力。
2021-04-09 10:40:13

你可以试试这个:

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

这是@Orbit三年后回答......
2021-03-11 10:40:13
+1 为简单起见,因为根据我的测试,此解决方案的运行速度比其他解决方案快约 10 倍
2021-03-28 10:40:13
例如我有两个“是”,你如何获得每个的位置?
2021-04-03 10:40:13
而且您还可以将它与变量一起使用:theString.split(myvar).length - 1您不能使用简单的正则表达式
2021-04-05 10:40:13
正如@Orbit 的回答中所讨论的,人们在旧版本的 Chrome 上得到不同的结果。使用这种方法我可能会有点谨慎。
2021-04-07 10:40:13

我的解决方案:

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

你还需要转义你的字符串或者countOcurrences('Hello...','.')==8不是 3
2021-03-21 10:40:13
也许返回 (str.match(regExp) || []).length 会更好;这样你就不会对正则表达式求值两次?
2021-03-23 10:40:13