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>
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Answer from Tim Down on Stack Overflowvar 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>
Run code snippetEdit code snippet Hide Results Copy to answer Expand
One liner using String.prototype.matchAll (ES2020):
[...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index)
Using your values:
const sourceStr = 'I learned to play the Ukulele in Lebanon.';
const searchStr = 'le';
const indexes = [...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index);
console.log(indexes); // [2, 25, 27, 33]
If you're worried about doing a spread and a map() in one line, I ran it with a for...of loop for a million iterations (using your strings). The one liner averages 1420ms while the for...of averages 1150ms on my machine. That's not an insignificant difference, but the one liner will work fine if you're only doing a handful of matches.
See matchAll on caniuse
Easy solution:
const str = "...";
const searchKeyword = "...";
const startingIndices = [];
let indexOccurence = str.indexOf(searchKeyword, 0);
while(indexOccurence >= 0) {
startingIndices.push(indexOccurence);
indexOccurence = str.indexOf(searchKeyword, indexOccurence + 1);
}
If you need something highly performant, you may look over specific text search/indexing algorithms like Aho–Corasick algorithm or Boyer–Moore string-search algorithm.
Really depends on your use case and if the text you're searching into is changing or is static and can be indexed beforehand for maximum performance.
const IndexString = (str1, str2, output=[]) =>{
for(let i = 0; i < str1.length -1; i++){
let arr = [];
for(let j = i; j < (i+str2.length) & i<str1.length; j++) arr.push(str1[j])
const findnew = arr.join('');
if(findnew===str2) output.push(i);
}
return output
}
console.log(IndexString("tiktok tok tok tik tok tik", "tik"))
Try something like:
var regexp = /abc/g;
var foo = "abc1, abc2, abc3, zxy, abc4";
var match, matches = [];
while ((match = regexp.exec(foo)) != null) {
matches.push(match.index);
}
console.log(matches);
Here is a working function:
function allIndexOf(str, toSearch) {
var indices = [];
for(var pos = str.indexOf(toSearch); pos !== -1; pos = str.indexOf(toSearch, pos + 1)) {
indices.push(pos);
}
return indices;
}
Use example:
> allIndexOf('dsf dsf kfvkjvcxk dsf', 'dsf');
[0, 4, 18]