757 votes

Comment compter l'occurrence d'une chaîne dans une autre chaîne?

Comment puis-je compter le nombre de fois qu'une chaîne particulière apparaît dans une autre chaîne. Par exemple, voici ce que j'essaie de faire en Javascript :

var temp = "Ceci est une chaîne.";
alert(temp.count("is")); //devrait afficher '2'

21 votes

Cela dépend de si vous acceptez des instances chevauchantes, par exemple var t = "sss"; Combien d'instances du sous-chaîne "ss" se trouvent dans la chaîne ci-dessus? 1 ou 2? Franchissez-vous chaque instance, ou déplacez-vous le caractère pointeur un par un, en cherchant la sous-chaîne?

4 votes

Un benchmark amélioré pour les réponses à cette question : jsperf.com/string-ocurrence-split-vs-match/2 (basé sur le benchmark de Kazzkiq).

0 votes

Compter le montant total d'un mot spécifique dans une chaîne JavaScript stackoverflow.com/a/65036248/4752258

1267voto

Rebecca Chernoff Points 7552

Le g dans l'expression régulière (globale) indique de rechercher dans toute la chaîne plutôt que de trouver juste la première occurrence. Cela correspond à is deux fois :

var temp = "Ceci est une chaîne.";
var count = (temp.match(/is/g) || []).length;
console.log(count);

Et, s'il n'y a pas de correspondance, cela renvoie 0 :

var temp = "Bonjour le monde !";
var count = (temp.match(/is/g) || []).length;
console.log(count);

1 votes

Assurez-vous simplement de mettre entre guillemets le mot à rechercher (is, dans ce cas) s'il contient des caractères spéciaux.

4 votes

Moderne et élégant, mais la solution de Vitimtk est beaucoup plus efficace. Que pensez-vous tous de son code ?

5 votes

Cela répond le mieux à la question. Si quelqu'un demandait "Comment puis-je faire cela 10 fois plus rapidement dans un cas spécial (sans regexps)", Vitimtk remporterait cette question.

269voto

Vitim.us Points 3340
/** Fonction qui compte les occurrences d'une sous-chaîne dans une chaîne;
 * @param {String} string               La chaîne
 * @param {String} subString            La sous-chaîne à rechercher
 * @param {Boolean} [allowOverlapping]  Optionnel. (Par défaut:false)
 *
 * @author Vitim.us https://gist.github.com/victornpb/7736865
 * @see Test unitaire https://jsfiddle.net/Victornpb/5axuh96u/
 * @see https://stackoverflow.com/a/7924240/938822
 */
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;
}

Utilisation

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

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

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

allowOverlapping

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

Correspondances:

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

Test unitaire

Comparatif

J'ai réalisé un test de performance et ma fonction est plus de 10 fois plus rapide que la fonction de recherche par expression régulière postée par gumbo. Dans mon test la chaîne contient 25 caractères avec 2 occurrences du caractère 'o'. J'ai exécuté la fonction 1 000 000 fois dans Safari.

Safari 5.1

Comparatif> Temps total d'exécution: 5617 ms (regexp)

Comparatif> Temps total d'exécution: 881 ms (ma fonction 6.4x plus rapide)

Firefox 4

Comparatif> Temps total d'exécution: 8547 ms (Rexexp)

Comparatif> Temps total d'exécution: 634 ms (ma fonction 13.5x plus rapide)


Modifications que j'ai apportées

  • longueur de la sous-chaîne mise en cache

  • ajout d'une conversion de type en chaîne.

  • ajout d'un paramètre optionnel 'allowOverlapping'

  • correction de la sortie correcte pour le cas de sous-chaîne vide "".

Gist

6 votes

J'ai répété ce test dans Safari 5 et obtenu des résultats similaires avec une petite chaîne de caractères (100b), mais avec une plus grande chaîne (16ko), l'expression régulière s'est exécutée plus rapidement pour moi. Pour une itération (pas 1 000 000), la différence était de moins d'une milliseconde de toute façon, donc je vote pour l'expression régulière.

2 votes

+1, mais vous vérifiez substring.length à chaque boucle, vous devriez envisager de le mettre en cache en dehors du while

1 votes

@ajax333221 OMG tu lis dans mes pensées, j'ai apporté cette amélioration il y a quelques jours, et j'allais éditer ma réponse jsperf.com/count-string-occurrence-in-string

171voto

Orbit Points 6928
function countInstances(string, word) {
   return string.split(word).length - 1;
}
console.log(countInstances("Ceci est une chaîne", "est"))

6 votes

Ceci est une approche non sécuritaire/inexacte, par exemple: countInstances("isisisisisis", "is") === 0.

0 votes

@Nick Craver : Cela me renvoie aussi six (en utilisant Google Chrome sur OS X).

6 votes

@Antal - Il semble y avoir un bug dans la version bêta précédente de Chrome, cela fonctionne après la mise à jour vers la dernière version. Cependant, je préfèrerais éviter cette méthode.

105voto

Freezy Ize Points 59

Vous pouvez essayer ceci :

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

19 votes

+1 pour la simplicité et parce que selon mes tests cette solution fonctionne ~10x plus rapidement que les autres!

0 votes

Par exemple, j'ai deux "is" comment obtenir la position de chacun?

0 votes

Comme discuté dans la réponse de @Orbit, les gens obtiennent des résultats différents sur les anciennes versions de Chrome. Je serais peut-être un peu prudent en utilisant cette méthode.

35voto

Gere Points 305

Ma solution:

var temp = "Ceci est une chaîne de caractères.";

function countOccurrences(str, value) {
  var regExp = new RegExp(value, "gi");
  return (str.match(regExp) || []).length;
}

console.log(countOccurrences(temp, 'est'));

5 votes

Peut-être serait-il préférable de renvoyer (str.match(regExp) || []).length; De cette façon, vous n'évaluez pas l'expression régulière deux fois ?

4 votes

Vous devez également échapper votre chaîne ou countOcurrences('Hello...','.')==8 et non pas 3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X