Come contare la presenza di stringhe nella stringa?

Come posso contare il numero di volte in cui una stringa particolare si verifica in un’altra stringa. Ad esempio, questo è quello che sto cercando di fare in Javascript:

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

La g nell’espressione regolare (abbreviazione globale ) dice di cercare l’intera stringa piuttosto che trovare la prima occorrenza:

 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 

gli incontri:

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

Test unitario

segno di riferimento

Ho fatto un test di benchmark e la mia funzione è più di 10 volte più veloce rispetto alla funzione di corrispondenza regexp pubblicata da gumbo. Nella mia stringa di test ha una lunghezza di 25 caratteri. con 2 occorrenze del carattere ‘o’. Ho eseguito 1.000.000 di volte in Safari.

Safari 5.1

Benchmark> Esecuzione totale del tempo: 5617 ms (espressione regolare)

Benchmark> Esecuzione totale del tempo: 881 ms (la mia funzione 6.4x più veloce)

Firefox 4

Benchmark> Esecuzione totale del tempo: 8547 ms (Rexexp)

Benchmark> Esecuzione totale del tempo: 634 ms (la mia funzione 13.5x più veloce)


Modifica: modifiche apportate

  • lunghezza della sottostringa memorizzata nella cache

  • aggiunto il cast alla stringa.

  • aggiunto il parametro opzionale ‘allowOverlapping’

  • corretto output corretto per “” sottostringa vuota.

nocciolo

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

Puoi provare questo:

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

La mia soluzione:

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

È ansible utilizzare la match per definire tale funzione:

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

Ecco la funzione più veloce!

Perché è più veloce?

  • Non seleziona char per carattere (con 1 eccezione)
  • Utilizza un po ‘di tempo e incrementa 1 var (il conteggio dei caratteri var) contro un ciclo for che controlla la lunghezza e incrementa 2 vars (di solito var i e una var con il conteggio dei caratteri)
  • Utilizza WAY meno vars
  • Non usa regex!
  • Utilizza una funzione (ottimisticamente ottimizzata)
  • Tutte le operazioni sono combinate come possono essere, evitando rallentamenti dovuti a più operazioni

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

Ecco una versione più lenta e più leggibile:

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

Questo è più lento a causa del contatore, nomi di var lunghi e uso improprio di 1 var.

Per usarlo, fai semplicemente questo:

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

Modifica: (2013/12/16)

NON usare con Opera 12.16 o precedente! ci vorranno quasi 2,5 volte più della soluzione regex!

Su Chrome, questa soluzione impiegherà tra 14ms e 20ms per 1.000.000 di caratteri.

La soluzione regex richiede 11-14ms per la stessa quantità.

L’utilizzo di una funzione (al di fuori di String.prototype ) richiederà circa 10-13 ms.

Ecco il codice utilizzato:

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

Il risultato di tutte le soluzioni dovrebbe essere 100.000!

Nota: se vuoi che questa funzione conti più di 1 carattere, cambia dove c=(c+'')[0] in c=c+''

La versione non 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 

La soluzione di Rebecca Chernoff : il golf del codice 🙂

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

Penso che lo scopo della regex sia molto diverso da indexOf . indexOf trova semplicemente l’occorrenza di una determinata stringa mentre in regex puoi usare caratteri jolly come [AZ] che significa che troverà qualsiasi carattere maiuscolo nella parola senza indicare il carattere reale.

Esempio:

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

Questo restituirà 2.

Super duper vecchio, ma avevo bisogno di fare qualcosa di simile oggi e pensavo solo a controllare SO in seguito. Funziona piuttosto veloce per me.

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

Consultare: – contare una sottostringa nella stringa per una spiegazione passo passo.

Basandosi su @ Vittim.us risposta sopra. Mi piace il controllo che il suo metodo mi dà, facilitando l’estensione, ma avevo bisogno di aggiungere insensibilità alle maiuscole e minuscole corrispondenze a parole intere con supporto per la punteggiatura. (ad esempio “bagno” è in “fare il bagno” ma non “fare il bagno”)

La regex di punteggiatura proveniva da: https://stackoverflow.com/a/25575009/497745 ( Come posso eliminare tutti i segni di punteggiatura da una stringa in JavaScript usando espressioni regolari? )

 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\\'!"#$%&\(\)*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]/.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\\'!"#$%&\(\)*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation { continue; //then this is not a match } } } ++n; } else break; } return n; } 

Sentitevi liberi di modificare e refactoring questa risposta se individuate bug o miglioramenti.

Per chiunque trovi questo thread in futuro, nota che la risposta accettata non restituirà sempre il valore corretto se lo generalizzi, dal momento che soffocherà su operatori di espressioni regolari come $ e . . Ecco una versione migliore, in grado di gestire qualsiasi ago:

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

Provalo

   

Versione semplice senza regex:

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

Ora questo è un thread molto vecchio che ho incontrato, ma come molti hanno spinto la loro risposta, ecco la mia nella speranza di aiutare qualcuno con questo semplice codice.

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

Risposta per Leandro Batista: solo un problema con l’espressione 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; } 

Un po ‘tardi ma, assumendo che abbiamo la seguente stringa:

 var temp = "This is a string."; 

Per prima cosa divideremo ciò che stai cercando, questo restituirà una serie di stringhe.

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

Quindi ne ricaviamo la lunghezza e ne sottraggiamo 1 poiché imposta i valori di default su una matrice di dimensione 1 e di conseguenza aumenta la sua dimensione ogni volta che trova un’occorrenza.

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

Puoi anche fare tutto questo in una riga come segue:

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

Spero che aiuti: D

Prova questo:

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