Comment puis-je compter le nombre de fois qu'une chaîne particulière se produit dans une autre chaîne. Par exemple, voici ce que j'essaie de faire en Javascript:
var temp = "This is a string.";
alert(temp.count("is")); //should output '2'
La g
dans l'expression régulière (abréviation de global ) indique de rechercher la chaîne entière plutôt que de rechercher la première occurrence. Cela correspond à is
deux fois:
var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Et, s'il n'y a pas de correspondance, il retourne 0
:
var temp = "Hello World!";
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;
}
occurrences("foofoofoo", "bar"); //0
occurrences("foofoofoo", "foo"); //3
occurrences("foofoofoo", "foofoo"); //1
occurrences("foofoofoo", "foofoo", true); //2
Allumettes:
foofoofoo
1 `----´
2 `----´
J'ai fait un test de référence et ma fonction est plus de 10 fois plus vite que la fonction de correspondance regexp postée par gumbo. Dans mon test la chaîne a une longueur de 25 caractères. avec 2 occurrences du caractère 'o'. JE exécuté 1 000 000 fois à Safari.
Safari 5.1
Indicateur de référence> Temps total d'exécution: 5617 ms (expression rationnelle)
Indice de référence> Temps d'exécution total: 881 ms (ma fonction est 6,4 fois plus rapide)
Firefox 4
Indicateur de référence> Temps total d'exécution: 8547 ms (Rexexp)
Indice de référence> Temps d'exécution total: 634 ms (ma fonction est 13.5x plus rapide)
Edit: modifications que j'ai faites
longueur de sous-chaîne mise en cache
ajout de la saisie de caractères à la chaîne.
ajout du paramètre optionnel 'allowOverlapping'
correction de la sortie correcte pour "" la casse de sous-chaîne vide.
function countInstances(string, Word) {
return string.split(Word).length - 1;
}
Vous pouvez essayer ceci:
var theString = "This is a string.";
console.log(theString.split("is").length - 1);
Ma solution:
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'));
Vous pouvez utiliser match
pour définir cette fonction:
String.prototype.count = function(search) {
var m = this.match(new RegExp(search.toString().replace(/(?=[.\\+*?[^\]$(){}\|])/g, "\\"), "g"));
return m ? m.length:0;
}
Juste le code-golf Rebecca Chernoff 's solution :-)
alert(("This is a string.".match(/is/g) || []).length);
La version 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
Voici la fonction la plus rapide!
Pourquoi est-ce plus rapide?
Toutes les opérations sont aussi combinées que possible, en évitant les ralentissements dus aux opérations multiples
String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
Voici une version plus lente et plus lisible:
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;
};
Celui-ci est plus lent à cause du compteur, des noms de variables longs et de l'utilisation abusive de 1 var.
Pour l'utiliser, vous faites simplement ceci:
'The char "a" only shows up twice'.timesCharExist('a');
Edit: (2013/12/16)
NE PAS utiliser avec Opera 12.16 ou plus ancien! il faudra presque 2,5 fois plus que la solution regex!
Sur chrome, cette solution prendra entre 14 ms et 20 ms pour 1 000 000 de caractères.
La solution regex prend 11-14 ms pour le même montant.
L'utilisation d'une fonction (en dehors de String.prototype
) prendra environ 10-13 ms.
Voici le code utilisé:
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');
Le résultat de toutes les solutions devrait être de 100 000!
Remarque: si vous voulez que cette fonction compte plus de 1 caractère, changez où est c=(c+'')[0]
en c=c+''
var temp = "This is a string.";
console.log((temp.match(new RegExp("is", "g")) || []).length);
Je pense que le but de regex est très différent de indexOf
.indexOf
simplement trouver l'occurrence d'une certaine chaîne alors que dans regex vous pouvez utiliser des jokers comme [A-Z]
qui signifie qu'il trouvera toute caractère capital dans le mot sans préciser le caractère réel.
Exemple:
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);
String.prototype.Count = function (find) {
return this.split(find).length - 1;
}
"This is a string.".Count("is");
Cela retournera 2.
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");
Référez-vous: - comptez qu'une sous-chaîne apparaît dans la chaîne pour une explication étape par étape.
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));
Utilisez get_occurrence (varS, string) pour rechercher l'occurrence des caractères et de la chaîne dans une chaîne.
Super duper vieux, mais je devais faire quelque chose comme ça aujourd'hui et ne pensais qu'à vérifier SO après. Ça marche assez vite pour moi.
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;
};
Si vous trouvez ce fil dans le futur, notez que la réponse acceptée ne renverra pas toujours la valeur correcte si vous la généralisez, car elle gênera les opérateurs regex comme $
et .
. Voici une meilleure version, qui peut gérer n'importe quel aiguille:
function occurrences (haystack, needle) {
var _needle = needle
.replace(/\[/g, '\\[')
.replace(/\]/g, '\\]')
return (
haystack.match(new RegExp('[' + _needle + ']', 'g')) || []
).length
}
S'appuyant sur @ Vittim.us, répondez ci-dessus. J'aime le contrôle que me donne sa méthode, ce qui facilite son extension, mais je devais ajouter l'insensibilité à la casse et limiter les correspondances à des mots entiers avec prise en charge de la ponctuation. (par exemple, "bain" est en "prendre un bain." mais pas "bain")
La regex de ponctuation provient de: https://stackoverflow.com/a/25575009/497745 ( Comment puis-je enlever toute la ponctuation d'une chaîne en JavaScript en utilisant 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;
}
N'hésitez pas à modifier et à reformuler cette réponse si vous remarquez des bogues ou des améliorations.
L'essayer
<?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>
Version simple sans regex:
var temp = "This is a string.";
var count = (temp.split('is').length - 1);
alert(count);
C’est un très vieux fil que j’ai rencontré, mais comme beaucoup ont insisté sur leur réponse, voici le mien dans l’espoir d'aider quelqu'un avec ce code simple.
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);
Je ne suis pas sûr que ce soit la solution la plus rapide, mais je l’ai préférée pour la simplicité et pour ne pas utiliser regex (je n’aime pas les utiliser!)
Réponse pour Leandro Batista: Juste un problème avec l’expression régulière.
"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>
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
}
Le même algorithme peut être présenté plus rapidement:
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 );
}
Cette solution est basée sur la méthode .replace()
qui accepte un RegEx comme premier paramètre et une fonction comme second paramètre que nous pouvons utiliser comme fermeture pour incrémenter un compteur.
/**
* 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
}
Usage
subStringCounter("foofoofoo", "bar"); //0
subStringCounter("foofoofoo", "foo"); //3
Personne ne le verra jamais, mais il est bon de ramener de temps en temps la récursion et les flèches
String.prototype.occurrencesOf = function(s, i) {
return (n => (n === -1) ? 0 : 1 + this.occurrencesOf(s, n + 1))(this.indexOf(s, (i || 0)));
};
Un peu tard mais supposons que nous ayons la chaîne suivante:
var temp = "This is a string.";
Tout d’abord, nous divisons ce que vous cherchez, cela retournera un tableau de chaînes.
var array = temp.split("is");
Ensuite, nous obtenons sa longueur et lui soustrayons 1 puisque la division par défaut est un tableau de taille 1 et que, par conséquent, nous incrémentons sa taille chaque fois qu’il trouve une occurrence.
var occurrenceCount = array.length - 1;
alert(occurrenceCount); //should output '2'
Vous pouvez également faire tout cela en une seule ligne comme suit:
alert("This is a string.".split("is").length - 1); //should output '2'
J'espère que ça aide: D
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;
}
<input " type="button" id="Btn_Validate" value="Validate" class="btn btn-info" />
<div class="textarea" id="test" contenteditable="true">HRABHRA</div>
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