144 votes

Comment trouver les indices de toutes les occurrences d'une chaîne dans une autre en JavaScript ?

J'essaie de trouver les positions de toutes les occurrences d'une chaîne dans une autre chaîne, sans tenir compte de la casse.

Par exemple, étant donné la chaîne de caractères :

I learned to play the Ukulele in Lebanon.

et la chaîne de recherche le Je souhaite obtenir le tableau :

[2, 25, 27, 33]

Les deux chaînes seront des variables - c'est-à-dire que je ne peux pas coder leurs valeurs en dur.

Je pensais que c'était une tâche facile pour les expressions régulières, mais après avoir lutté pendant un certain temps pour en trouver une qui fonctionnerait, je n'ai pas eu de chance.

J'ai trouvé cet exemple sur la façon d'y parvenir en utilisant .indexOf() Mais il doit bien y avoir un moyen plus concis de le faire.

4voto

Hoffmann Points 391

Si vous souhaitez simplement trouver la position de tous les matchs, j'aimerais vous indiquer une petite astuce :

var haystack = 'I learned to play the Ukulele in Lebanon.',
    needle = 'le',
    splitOnFound = haystack.split(needle).map(function (culm)
    {
        return this.pos += culm.length + needle.length
    }, {pos: -needle.length}).slice(0, -1); // {pos: ...} – Object wich is used as this

console.log(splitOnFound);

Cela peut ne pas être applicable si vous avez un RegExp de longueur variable, mais pour certains, cela peut être utile.

Il est sensible à la casse. Pour éviter la casse, utilisez String.toLowerCase avant.

3voto

Victor Points 75
const findAllOccurrences = (str, substr) => {
  str = str.toLowerCase();

  let result = [];

  let idx = str.indexOf(substr)

  while (idx !== -1) {
    result.push(idx);
    idx = str.indexOf(substr, idx+1);
  }
  return result;
}

console.log(findAllOccurrences('I learned to play the Ukulele in Lebanon', 'le'));

2voto

Je recommande la réponse de Tim. Cependant, la réponse de Tim n'est pas suffisante, ce commentaire par @blazs déclare "Supposons que searchStr=aaa y que str=aaaaaa . Alors, au lieu de trouver 4 occurrences, votre code n'en trouvera que 2 parce que vous faites des sauts par searchStr.length dans la boucle", ce qui est vrai si l'on regarde le code de Tim, en particulier cette ligne ici : startIndex = index + searchStrLen; Le code de Tim ne serait pas en mesure de trouver une instance de la chaîne recherchée dont la longueur est inférieure à la sienne. J'ai donc modifié la réponse de Tim :

function getIndicesOf(searchStr, str, caseSensitive) {
    var startIndex = 0, index, indices = [];
    if (!caseSensitive) {
        str = str.toLowerCase();
        searchStr = searchStr.toLowerCase();
    }
    while ((index = str.indexOf(searchStr, startIndex)) > -1) {
        indices.push(index);
        startIndex = index + 1;
    }
    return indices;
}
var searchStr = prompt("Enter a string.");
var str = prompt("What do you want to search for in the string?");
var indices = getIndicesOf(str, searchStr);

document.getElementById("output").innerHTML = indices + "";

<div id="output"></div>

Le remplacer par + 1 au lieu de + searchStrLen permettra à l'index 1 d'être dans le tableau des indices si j'ai un str de aaaaaa et une chaîne de recherche de aaa .

P.S. Si quelqu'un souhaite que des commentaires soient ajoutés au code pour en expliquer le fonctionnement, qu'il le dise et je me ferai un plaisir de répondre à sa demande.

1voto

Kapil Tiwari Points 154

Voici un extrait de code simple :

function getIndexOfSubStr(str, searchToken, preIndex, output) {
    var result = str.match(searchToken);
    if (result) {
        output.push(result.index +preIndex);
        str=str.substring(result.index+searchToken.length);
        getIndexOfSubStr(str, searchToken, preIndex, output)
    }
    return output;
}

var str = "my name is 'xyz' and my school name is 'xyz' and my area name is 'xyz' ";
var searchToken ="my";
var preIndex = 0;

console.log(getIndexOfSubStr(str, searchToken, preIndex, []));

0voto

Cao Mạnh Quang Points 404

Suivez la réponse de @jcubic, sa solution a causé une petite confusion pour mon cas
Par exemple var result = indexes('aaaa', 'aa') renverra [0, 1, 2] au lieu de [0, 2]
J'ai donc modifié un peu sa solution pour qu'elle corresponde à mon cas.

function indexes(text, subText, caseSensitive) {
    var _source = text;
    var _find = subText;
    if (caseSensitive != true) {
        _source = _source.toLowerCase();
        _find = _find.toLowerCase();
    }
    var result = [];
    for (var i = 0; i < _source.length;) {
        if (_source.substring(i, i + _find.length) == _find) {
            result.push(i);
            i += _find.length;  // found a subText, skip to next position
        } else {
            i += 1;
        }
    }
    return result;
}

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