How to find indices of all occurrences of one string in another in JavaScript?

Bungle picture Bungle · Aug 5, 2010 · Viewed 135.3k times · Source

I'm trying to find the positions of all occurrences of a string in another string, case-insensitive.

For example, given the string:

I learned to play the Ukulele in Lebanon.

and the search string le, I want to obtain the array:

[2, 25, 27, 33]

Both strings will be variables - i.e., I can't hard-code their values.

I figured that this was an easy task for regular expressions, but after struggling for a while to find one that would work, I've had no luck.

I found this example of how to accomplish this using .indexOf(), but surely there has to be a more concise way to do it?

Answer

Tim Down picture Tim Down · Aug 5, 2010
var str = "I learned to play the Ukulele in Lebanon."
var regex = /le/gi, result, indices = [];
while ( (result = regex.exec(str)) ) {
    indices.push(result.index);
}

UPDATE

I failed to spot in the original question that the search string needs to be a variable. I've written another version to deal with this case that uses indexOf, so you're back to where you started. As pointed out by Wrikken in the comments, to do this for the general case with regular expressions you would need to escape special regex characters, at which point I think the regex solution becomes more of a headache than it's worth.

function getIndicesOf(searchStr, str, caseSensitive) {
    var searchStrLen = searchStr.length;
    if (searchStrLen == 0) {
        return [];
    }
    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 + searchStrLen;
    }
    return indices;
}

var indices = getIndicesOf("le", "I learned to play the Ukulele in Lebanon.");

document.getElementById("output").innerHTML = indices + "";
<div id="output"></div>