Como contar a ocorrência da string em string?

Como posso contar o número de vezes que uma string específica ocorre em outra string. Por exemplo, é isso que estou tentando fazer em Javascript:

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

   

O g na expressão regular (abreviação de global ) diz para pesquisar toda a string, em vez de apenas encontrar a primeira ocorrência:

 var temp = "This is a string."; var count = (temp.match(/is/g) || []).length; console.log(count); 
 /** 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; } 

Uso

 occurrences("foofoofoo", "bar"); //0 occurrences("foofoofoo", "foo"); //3 occurrences("foofoofoo", "foofoo"); //1 

allowOverlapping

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

Fósforos:

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

Teste de unidade

Referência

Eu fiz um teste de benchmark e minha function é mais de 10 vezes mais rápida do que a function de correspondência de expressões regulares postada pelo gumbo. Na minha cadeia de teste é de 25 caracteres de comprimento. com 2 ocorrências do caractere ‘o’. Eu executei 1 000 000 vezes no Safari.

Safari 5.1

Referência> Tempo total de execução: 5617 ms (regexp)

Referência> Tempo total de execução: 881 ms (minha function 6,4 vezes mais rápida)

Firefox 4

Referência> Tempo total de execução: 8547 ms (Rexexp)

Referência> Tempo total de execução: 634 ms (minha function é 13.5x mais rápida)


Editar: alterações que fiz

  • comprimento de substring em cache

  • acrescentou o tipo de conversão para string.

  • parâmetro opcional ‘allowOverlapping’ adicionado

  • saída correta corrigida para “” checkbox de substring vazia.

Essência

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

Você pode tentar isto:

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

Minha solução:

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

Você pode usar a match para definir essa function:

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

Aqui está a function mais rápida!

Por que é mais rápido?

  • Não verifica char por char (com 1 exceção)
  • Usa um tempo e incrementa 1 var (o char count var) contra um loop for verificando o comprimento e incrementando 2 vars (usualmente var i e um var com o char count)
  • Usa WAY menos vars
  • Não usa regex!
  • Usa uma function (otimizada) altamente otimizada
  • Todas as operações são tão combinadas quanto possível, evitando lentidão devido a múltiplas operações

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

Aqui está uma versão mais lenta e mais legível:

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

Este é mais lento por causa do contador, nomes longos de var e uso indevido de 1 var.

Para usá-lo, você simplesmente faz isso:

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

Editar: (2013/12/16)

Não use com o Opera 12.16 ou mais! vai demorar quase 2,5 vezes mais do que a solução de regex!

No chrome, esta solução levará entre 14 e 20 ms para 1.000.000 caracteres.

A solução regex leva 11-14ms para o mesmo valor.

Usando uma function (fora String.prototype ) levará cerca de 10-13ms.

Aqui está o código usado:

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

O resultado de todas as soluções deve ser de 100.000!

Nota: se você quiser que esta function conte mais de 1 char, altere onde é c=(c+'')[0] para c=c+''

A versão não-regex:

  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 

Apenas a solução de Rebecca Chernoff para o golfe com código 🙂

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

Eu acho que o propósito da regex é muito diferente do indexOf . indexOf simplesmente encontre a ocorrência de uma certa string enquanto na regex você pode usar curingas como [AZ] que significa que encontrará qualquer caractere maiúsculo na palavra sem declarar o caractere real.

Exemplo:

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

String.prototype.Count = function (find) { return this.split(find).length - 1; } "This is a string.".Count("is");

Isso retornará 2.

Super duper old, mas eu precisava fazer algo assim hoje e só pensei em checar isso depois. Funciona bem rápido para mim.

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

Consulte: – contar uma substring aparece na string para explicação passo a passo.

Baseando-se na resposta @ Vittim.us acima. Eu gosto do controle que seu método me dá, facilitando a extensão, mas eu precisava adicionar insensibilidade a maiúsculas e limitar as correspondências a palavras inteiras com suporte para pontuação. (por exemplo, “banho” está em “tomar banho”, mas não “tomar banho”)

A regex de pontuação veio de: https://stackoverflow.com/a/25575009/497745 ( Como posso tirar toda a pontuação de uma string em JavaScript usando 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; } 

Por favor, sinta-se à vontade para modificar e refatorar esta resposta se você identificar erros ou melhorias.

Para qualquer um que encontrar esse thread no futuro, observe que a resposta aceita nem sempre retornará o valor correto se você generalizar, já que ele irá se afogar em operadores regex como $ e . . Aqui está uma versão melhor, que pode manipular qualquer agulha:

 function occurrences (haystack, needle) { var _needle = needle .replace(/\[/g, '\\[') .replace(/\]/g, '\\]') return ( haystack.match(new RegExp('[' + _needle + ']', 'g')) || [] ).length } 
 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)); 

Tente

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

Versão simples sem regex:

 var temp = "This is a string."; var count = (temp.split('is').length - 1); alert(count); 

Agora, este é um tópico muito antigo que eu já vi, mas, como muitos deles pressionaram suas respostas, aqui está o meu na esperança de ajudar alguém com esse código simples.

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

Resposta para Leandro Batista: apenas um problema com a expressão regex.

  "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()); }); 
  
What do you wanna count
Number of occurences = 0
 var countInstances = function(body, target) { var globalcounter = 0; var concatstring = ''; for(var i=0,j=target.length;i 2 console.log( countInstances('ababa', 'aba') ); // ==> 2 console.log( countInstances('aaabbb', 'ab') ); // ==> 1 
 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; } 

Um pouco atrasado, mas assumindo que temos a seguinte string:

 var temp = "This is a string."; 

Primeiro nós dividimos em qualquer coisa que você esteja procurando, isso irá retornar um array de strings.

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

Em seguida, obtemos o tamanho dele e subtraímos 1 a ele, pois o padrão é dividido em uma matriz de tamanho 1 e, por conseqüência, ele aumenta seu tamanho toda vez que encontra uma ocorrência.

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

Você também pode fazer tudo isso em uma linha da seguinte maneira:

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

Espero que ajude: D

Tente isto:

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