d0g
d0g

Reputation: 1389

Get index of last occurence of matched string?

I want to get the index of the last occurrence of a character in a string which is part of a match string. What's the most efficient way to do this?

Something like match(/[\.,;]/g) but I want the index in the original string of the last element of the returned array, the way that match(/[\.,;]/) gives the index of the first match.

E.g., if string is Hello, this is a test. foo I want the index of the last period/comma/semicolon.

The best solution I've come up with is reversing the string and finding first match:

text.length - text.split('').reverse().join('').match(/[\.,;]/).index - 1

Upvotes: 4

Views: 920

Answers (4)

Redu
Redu

Reputation: 26161

This is infact a very good question to show one of the overlooked and most underrated string methods. String.search(). Which takes a regexp to do it's things and returns the index of the match or -1 if not found.

Get me the last one's index often calls for .lastIndexOf() yet sometimes when we search for optional targets then it is useless or not sufficient the least. Such as the last appearance of ".", "," or ";". So here is your multiple choice .lastIndexOf() function.

let s = ",., .;, ,...;; ;_-_,.;---",
    i = s.search(/[\.,;](?!.*[\.,;])/);
console.log(`The index is ${i} and the character at that position is "${s[i]}".`);

Upvotes: 0

symlink
symlink

Reputation: 12209

let text = 'Hello, this is a test. foo'; 
let lastChar = [...text.matchAll(/[\.,;]/g)].pop().index
console.log(lastChar)

Upvotes: 2

Tony Nguyen
Tony Nguyen

Reputation: 3488

Your solution is not efficient because this is go through every character text.length - text.split('').reverse().join('').match(/[\.,;]/).index - 1. You can simply using a for loop: Run and check the code below:

const text = "Hello, this is a test. foo"
const validChecker = [".",",",";"] // any char you want
const findLast = (text,validChecker) =>{
  if(!text) return
  for(let i = text.length -1; i>=0; i--){
    if(validChecker.includes(text[i])){
      return i
    }
  }
}

console.log(findLast(text,validChecker))

Upvotes: 0

Aplet123
Aplet123

Reputation: 35502

A bit of a hacky solution, but you can use a function as an argument to replace:

const matches = [];
const text = "foo.bar,qaz";
// don't use any capturing groups otherwise the function will be messed up
text.replace(/[\.,;]/g, (match, offset) => matches.push(offset));
console.log(matches[matches.length - 1]);

Upvotes: 1

Related Questions