Reputation: 1389
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
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
Reputation: 12209
let text = 'Hello, this is a test. foo';
let lastChar = [...text.matchAll(/[\.,;]/g)].pop().index
console.log(lastChar)
Upvotes: 2
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
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