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

时间:2010-10-24 18:39:15

标签: javascript regex string

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

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

39 个答案:

答案 0 :(得分:867)

正则表达式中的g global 的缩写)表示搜索整个字符串而不是仅查找第一个匹配项。这匹配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);

答案 1 :(得分:213)

/** 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

allowOverlapping

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

匹配

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

单元测试

基准

  

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

     

Safari 5.1

     

基准&GT;总执行时间:5617 ms(正则表达式)

     

基准&GT;总执行时间:881 ms(我的功能快6.4倍)

     

Firefox 4

     

基准&GT;总执行时间:8547 ms(Rexexp)

     

基准&GT;总执行时间:634毫秒(我的功能快13.5倍)

     
     

编辑:我做过的更改

     
      
  • 缓存子字符串长度

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

  •   
  • 添加了可选的'allowOverlapping'参数

  •   
  • 修复了“”空子串案例的正确输出。

  •   
要旨

答案 2 :(得分:93)

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

答案 3 :(得分:75)

你可以试试这个:

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

答案 4 :(得分:32)

我的解决方案:

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

答案 5 :(得分:18)

您可以使用match来定义此类功能:

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

答案 6 :(得分:9)

只需代码打高尔夫Rebecca Chernoffsolution: - )

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

答案 7 :(得分:9)

非正则表达式版本:

 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

答案 8 :(得分:8)

这是最快的功能!

为什么它更快?

  • 不检查char的char(有1个例外)
  • 使用一段时间并增加1 var(字符计数var)与for循环检查长度并增加2个变量(通常是var i和带有char计数的var)
  • 使用WAY less vars
  • 不使用正则表达式!
  • 使用(希望)高度优化的功能
  • 所有操作都尽可能合并,避免因多次操作导致的速度降低

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

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

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

由于计数器,长var名称和1 var。

的误用,这个比较慢

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

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

编辑:(2013/12/16)

请勿使用Opera 12.16或更早版本!它将比正则表达式解决方案多出近2.5倍!

在Chrome上,对于1,000,000个字符,此解决方案需要14毫秒到20毫秒。

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

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

以下是使用的代码:

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

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

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

答案 9 :(得分:7)

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

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

这将返回2.

答案 10 :(得分:7)

&#13;
&#13;
var temp = "This is a string.";
console.log((temp.match(new RegExp("is", "g")) || []).length);
&#13;
&#13;
&#13;

答案 11 :(得分:4)

我认为正则表达式的目的与indexOf有很大不同。 indexOf只是在正则表达式中找到某个字符串的出现,您可以使用[A-Z]之类的通配符,这意味着它会在单词中找到任何大写字符,而不会说明实际字符。

示例:

 var index = "This is a string".indexOf("is");
 console.log(index);
 var length = "This is a string".match(/[a-z]/g).length;
 // where [a-z] is a regex wildcard expression thats why its slower
 console.log(length);

答案 12 :(得分:3)

Super duper old,但我今天需要做这样的事情,之后才考虑检查SO。对我来说工作得很快。

String.prototype.count = function(substr,start,overlap) {
    overlap = overlap || false;
    start = start || 0;

    var count = 0, 
        offset = overlap ? 1 : substr.length;

    while((start = this.indexOf(substr, start) + offset) !== (offset - 1))
        ++count;
    return count;
};

答案 13 :(得分:3)

       var myString = "This is a string.";
        var foundAtPosition = 0;
        var Count = 0;
        while (foundAtPosition != -1)
        {
            foundAtPosition = myString.indexOf("is",foundAtPosition);
            if (foundAtPosition != -1)
            {
                Count++;
                foundAtPosition++;
            }
        }
        document.write("There are " + Count + " occurrences of the word IS");

请参阅: - count a substring appears in the string了解分步说明。

答案 14 :(得分:3)

对于将来发现此主题的任何人,请注意,如果您对其进行概括,则接受的答案将不会始终返回正确的值,因为它会阻塞$.等正则表达式运算符。这是一个更好的版本,可以处理任何针:

function occurrences (haystack, needle) {
  var _needle = needle
    .replace(/\[/g, '\\[')
    .replace(/\]/g, '\\]')
  return (
    haystack.match(new RegExp('[' + _needle + ']', 'g')) || []
  ).length
}

答案 15 :(得分:3)

建立在@ Vittim.us上面的答案。我喜欢他的方法给我的控件,使其易于扩展,但我需要添加不区分大小写并限制匹配整个单词并支持标点符号。 (例如&#34;洗澡&#34;在&#34;洗澡。&#34;但不是&#34;洗澡&#34;)

标点符号正则表达式来自:https://stackoverflow.com/a/25575009/497745How can I strip all punctuation from a string in JavaScript using regex?

function keywordOccurrences(string, subString, allowOverlapping, caseInsensitive, wholeWord)
{

    string += "";
    subString += "";
    if (subString.length <= 0) return (string.length + 1); //deal with empty strings

    if(caseInsensitive)
    {            
        string = string.toLowerCase();
        subString = subString.toLowerCase();
    }

    var n = 0,
        pos = 0,
        step = allowOverlapping ? 1 : subString.length,
        stringLength = string.length,
        subStringLength = subString.length;

    while (true)
    {
        pos = string.indexOf(subString, pos);
        if (pos >= 0)
        {
            var matchPos = pos;
            pos += step; //slide forward the position pointer no matter what

            if(wholeWord) //only whole word matches are desired
            {
                if(matchPos > 0) //if the string is not at the very beginning we need to check if the previous character is whitespace
                {                        
                    if(!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.test(string[matchPos - 1])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }

                var matchEnd = matchPos + subStringLength;
                if(matchEnd < stringLength - 1)
                {                        
                    if (!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }
            }

            ++n;                
        } else break;
    }
    return n;
}

如果您发现错误或改进,请随时修改并重构此答案。

答案 16 :(得分:3)

function get_occurrence(varS,string){//Find All Occurrences
        c=(string.split(varS).length - 1);
        return c;
    }
    temp="This is a string.";
    console.log("Total Occurrence is "+get_occurrence("is",temp));

使用get_occurrence(varS,string)查找String中字符和字符串的出现。

答案 17 :(得分:2)

现在这是一个非常古老的线索我遇到了但很多人已经推动了他们的答案,这是我的希望用这个简单的代码来帮助某人。

var search_value = "This is a dummy sentence!";
var letter = 'a'; /*Can take any letter, have put in a var if anyone wants to use this variable dynamically*/
letter = letter[letter.length - 1];
var count;
for (var i = count = 0; i < search_value.length; count += (search_value[i++] == letter));
console.log(count);

我不确定它是否是最快的解决方案,但我更喜欢它的简单性和不使用正则表达式(我只是不喜欢使用它们!)

答案 18 :(得分:2)

没有正则表达式的简单版本:

&#13;
&#13;
var temp = "This is a string.";

var count = (temp.split('is').length - 1);

alert(count);
&#13;
&#13;
&#13;

答案 19 :(得分:2)

试试吧

<?php 
$str = "33,33,56,89,56,56";
echo substr_count($str, '56');
?>

<script type="text/javascript">
var temp = "33,33,56,89,56,56";
var count = temp.match(/56/g);  
alert(count.length);
</script>

答案 20 :(得分:1)

没人会看到这一点,但是偶尔带回递归和箭头功能(很好的双关语)是很好的

String.prototype.occurrencesOf = function(s, i) {
 return (n => (n === -1) ? 0 : 1 + this.occurrencesOf(s, n + 1))(this.indexOf(s, (i || 0)));
};

答案 21 :(得分:1)

ES2020 提供了一个新的 MatchAll,它可能在这个特定的上下文中有用。

这里我们创建了一个新的 RegExp,请确保您将 'g' 传递给函数。

使用 Array.from 转换结果并计算长度,根据原始请求者的期望输出返回 2。

let strToCheck = RegExp('is', 'g')
let matchesReg = "This is a string.".matchAll(strToCheck)
console.log(Array.from(matchesReg).length) // 2

答案 22 :(得分:1)

 function substrCount( str, x ) {
   let count = -1, pos = 0;
   do {
     pos = str.indexOf( x, pos ) + 1;
     count++;
   } while( pos > 0 );
   return count;
 }

答案 23 :(得分:0)

&#13;
&#13;
var s = "1";replaced word
var a = "HRA"; //have to replace 
var str = document.getElementById("test").innerHTML;
var count = str.split(a).length - 1;
for (var i = 0; i < count; i++) {
    var s = "1";
    var a = "HRA";
    var str = document.getElementById("test").innerHTML;
    var res = str.replace(a, s);
    document.getElementById("test").innerHTML = res;
}
&#13;
&#13;
&#13;

&#13;
&#13;
<input " type="button" id="Btn_Validate" value="Validate" class="btn btn-info" />
<div class="textarea"  id="test" contenteditable="true">HRABHRA</div>
&#13;
&#13;
&#13;

答案 24 :(得分:0)

有点晚了,但假设我们有以下字符串:

var temp = "This is a string.";

首先,我们分割你想要匹配的内容,这将返回一个字符串数组。

var array = temp.split("is");

然后我们得到它的长度并减去1,因为split默认为一个大小为1的数组,因此每当它找到一个匹配项时就会增加它的大小。

var occurrenceCount = array.length - 1;
alert(occurrenceCount); //should output '2'

您也可以按如下方式在一行中执行所有操作:

alert("This is a string.".split("is").length - 1); //should output '2'

希望它有所帮助:D

答案 25 :(得分:0)

&#13;
&#13;
var countInstances = function(body, target) {
  var globalcounter = 0;
  var concatstring  = '';
  for(var i=0,j=target.length;i<body.length;i++){
    concatstring = body.substring(i-1,j);
    
    if(concatstring === target){
       globalcounter += 1;
       concatstring = '';
    }
  }
  
  
  return globalcounter;
 
};

console.log(   countInstances('abcabc', 'abc')   ); // ==> 2
console.log(   countInstances('ababa', 'aba')   ); // ==> 2
console.log(   countInstances('aaabbb', 'ab')   ); // ==> 1
&#13;
&#13;
&#13;

答案 26 :(得分:0)

此解决方案基于.replace()方法,该方法接受RegEx作为第一个参数,并使用function as second parameter作为闭包来增加计数器...

/**
 * Return the frequency of a substring in a string
 * @param {string} string - The string.
 * @param {string} string - The substring to count.
 * @returns {number} number - The frequency.
 * 
 * @author Drozerah https://gist.github.com/Drozerah/2b8e08d28413d66c3e63d7fce80994ce
 * @see https://stackoverflow.com/a/55670859/9370788
 */
const subStringCounter = (string, subString) => {

    let count = 0
    string.replace(new RegExp(subString, 'gi'), () => count++)
    return count
}

用法

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

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

答案 27 :(得分:0)

came across this post.

let str = 'As sly as a fox, as strong as an ox';

let target = 'as'; // let's look for it

let pos = 0;
while (true) {
  let foundPos = str.indexOf(target, pos);
  if (foundPos == -1) break;

  alert( `Found at ${foundPos}` );
  pos = foundPos + 1; // continue the search from the next position
}

可以将同一算法的布局缩短:

let str = "As sly as a fox, as strong as an ox";
let target = "as";

let pos = -1;
while ((pos = str.indexOf(target, pos + 1)) != -1) {
  alert( pos );
}

答案 28 :(得分:0)

尝试

let allData =  "This is a string.";
let searchString = 'is';
let regularExp = new RegExp(searchString, 'g');
let occurArray = allData.match(regularExp);
let count = (occurArray || []).length;
alert(count); 

小提琴链接:https://jsfiddle.net/rajaramtt/gn0dtsjc/1/

答案 29 :(得分:0)


substr_count从php转换为Javascript


function substr_count (haystack, needle, offset, length) { 
  // eslint-disable-line camelcase
  //  discuss at: https://locutus.io/php/substr_count/
  // original by: Kevin van Zonneveld (https://kvz.io)
  // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Brett Zamir (https://brett-zamir.me)
  // improved by: Thomas
  //   example 1: substr_count('Kevin van Zonneveld', 'e')
  //   returns 1: 3
  //   example 2: substr_count('Kevin van Zonneveld', 'K', 1)
  //   returns 2: 0
  //   example 3: substr_count('Kevin van Zonneveld', 'Z', 0, 10)
  //   returns 3: false

  var cnt = 0

  haystack += ''
  needle += ''
  if (isNaN(offset)) {
    offset = 0
  }
  if (isNaN(length)) {
    length = 0
  }
  if (needle.length === 0) {
    return false
  }
  offset--

  while ((offset = haystack.indexOf(needle, offset + 1)) !== -1) {
    if (length > 0 && (offset + needle.length) > length) {
      return false
    }
    cnt++
  }

  return cnt
}

查看Locutus对Php的substr_count函数的翻译

答案 30 :(得分:0)

Leandro Batista的答案: 只是正则表达式的一个问题。

 "use strict";
 var dataFromDB = "testal";
 
  $('input[name="tbInput"]').on("change",function(){
	var charToTest = $(this).val();
	var howManyChars = charToTest.length;
	var nrMatches = 0;
	if(howManyChars !== 0){
		charToTest = charToTest.charAt(0);
		var regexp = new RegExp(charToTest,'gi');
		var arrMatches = dataFromDB.match(regexp);
		nrMatches = arrMatches ? arrMatches.length : 0;
	}
		$('#result').html(nrMatches.toString());

  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
What do you wanna count <input type="text" name="tbInput" value=""><br />
Number of occurences = <span id="result">0</span>
</div>

答案 31 :(得分:0)

您可以尝试

let count = s.length - s.replace(/is/g, "").length;

答案 32 :(得分:0)

参数: ustring:超集字符串 countChar:子字符串

在JavaScript中计算子字符串出现的函数:

import { 
  Text, 
  View,
  Alert
} from 'react-native';

答案 33 :(得分:0)

var str = 'stackoverflow';
var arr = Array.from(str);
console.log(arr);

for (let a = 0; a <= arr.length; a++) {
  var temp = arr[a];
  var c = 0;
  for (let b = 0; b <= arr.length; b++) {
    if (temp === arr[b]) {
      c++;
    }

  }
  console.log(`the ${arr[a]} is counted for ${c}`)
}

答案 34 :(得分:0)

第二次减少迭代次数(仅当子字符串的第一个字母匹配时)但仍然使用 2 个 for 循环:

   function findSubstringOccurrences(str, word) {
        let occurrences = 0;
        for(let i=0; i<str.length; i++){
            if(word[0] === str[i]){ // to make it faster and iterate less
                for(let j=0; j<word.length; j++){
                    if(str[i+j] !== word[j]) break;
                    if(j === word.length - 1) occurrences++;
                }
            }
        }
        return occurrences;
    }
    
    console.log(findSubstringOccurrences("jdlfkfomgkdjfomglo", "omg"));

答案 35 :(得分:0)

//Try this code

const countSubStr = (str, search) => {
    let arrStr = str.split('');
    let i = 0, count = 0;

    while(i < arrStr.length){
        let subStr = i + search.length + 1 <= arrStr.length ?
                  arrStr.slice(i, i+search.length).join('') :
                  arrStr.slice(i).join('');
        if(subStr === search){
            count++;
            arrStr.splice(i, search.length);
        }else{
            i++;
        }
    }
    return count;
  }

答案 36 :(得分:0)

一种简单的方法是将字符串拆分为所需单词,即我们要计算出现次数的单词,然后从部分数中减去 1:

function checkOccurences(string, word) {
      return string.split(word).length - 1;
}
const text="Let us see. see above, see below, see forward, see backward, see left, see right until we will be right"; 
const count=countOccurences(text,"see "); // 2

答案 37 :(得分:0)

var mystring = 'This is the lorel ipsum text';
var mycharArray = mystring.split('');
var opArr = [];
for(let i=0;i<mycharArray.length;i++){
if(mycharArray[i]=='i'){//match the character you want to match
    opArr.push(i);
  }}
console.log(opArr); // it will return matching index position
console.log(opArr.length); // it will return length

答案 38 :(得分:-1)

试试这个:

function countString(str, search){
    var count=0;
    var index=str.indexOf(search);
    while(index!=-1){
        count++;
        index=str.indexOf(search,index+1);
    }
    return count;
}