user7159290
user7159290

Reputation:

JS Match all occurrences of substring in a string

I have seen this link but my question is different. javascript regex match all occurrences of substring?

match() function in JS can be used to match a substring in a string.

When I run this code, I got output like this.

let s = 'Hello_HaHaHaHackerRank';
let hacker = s.match('HaHa');
console.log(hacker);
console.log(hacker.index);
console.log(hacker.input);

Output:

["HaHa"]
6
Hello_HaHaHaHackerRank

hacker.index is giving one first occurrence of the pattern. But the string has three times HaHa. One is at index 6, another is at index 8 and another is at index 10.

Can anyone please explain, How can I get the occurrences of all substring?

Upvotes: 1

Views: 4776

Answers (3)

Pedro Papadópolis
Pedro Papadópolis

Reputation: 403

Accepted answer breaks on the following edge case:

// Current accepted answer
function findOccurrences(needle, haystack) {
    let hacker = [];
    let i = 0, j=0;
    while (~(i = haystack.indexOf (needle,++i))) hacker.push(i);
    return hacker;
}

console.log(
    'should return 3 occurrences when word is shared among matches', 
    JSON.stringify(findOccurrences('HaHa', 'Hello_HaHaHaHackerRank')) === "[6,8,10]") 
        ? 'Pass' 
        : 'Fail';
// WILL PASS

console.log(
    'should return 3 occurrences when needle is in the beginning of haystack', 
    JSON.stringify(findOccurrences('HaHa', 'HaHaHaHackerRank')) === "[0,2,4]") 
        ? 'Pass' 
        : 'Fail';
// WILL NOT PASS

One way to fix the implementation is to move the incrementation logic to inside while's callback:

function findOccurrences(needle, haystack) {
    let hacker = [];
    let i = 0, j=0;
    while (~(i = haystack.indexOf (needle,i))) { hacker.push(i); ++i; };
    return hacker;
}

Now the tests will pass.

Upvotes: 0

Moritz Roessler
Moritz Roessler

Reputation: 8651

indexOf has a fromIndex value you can use with a while loop str.indexOf(searchValue[, fromIndex])

let s = 'Hello_HaHaHaHackerRank';
let find = 'HaHa'
let hacker = [];
let i = 0, j=0;
while (~(i = s.indexOf (find,i + find.length))) hacker.push(i);
console.log (hacker)

If you want to include all occurences, don't add the length of the word.

while (~(i = s.indexOf (find,++i))) hacker.push (i)

Upvotes: 3

Stefano Maglione
Stefano Maglione

Reputation: 4160

Try with:

let re = /HaHa/g,
str = "Hello_HaHaHaHackerRank";
while ((match = re.exec(str)) != null) {
  console.log("match found at " + match.index);
}

Upvotes: 1

Related Questions