Replace last occurrence of "a" in a string

Asked

Viewed 1,288 times

3

How do I replace the last occurrence of a in a string?

var myFrase = prompt(" Digite sua frase aqui: ");

for (i = 0; i < myFrase.length; i++) {
  result = myFrase.charAt(i);
  if (result == "a") {
    str = myFrase.replace(/a$/m, "@");
  }
}
document.write("<br> Substituição do a pelo @: " + str + "<br>");

I’m trying to do it this way, but it just replaces the a for @ when the a is at the end of the word. Someone can help me?

2 answers

2

If you seek to exchange all a for @ you don’t need to have a for.
Just use your own regex in the string directly:

var myFrase = 'aaaa';
var trocada = myFrase.replace(/a$/m, "@");
console.log(trocada);

If you want to change all the and not just the last one, take the $ of regex.

2

In fact, the regex you used (/a$/) only replaces the a in the end precisely because you used the bookmark $, meaning "end of string". In addition, the for is unnecessary as regex will already traverse the entire string looking for a.


A solution with regex is to use /a([^a]*)$/. The excerpt [^a] means "all that nay for the letter a" and the quantifier * means "zero or more occurrences". And all this is in parentheses to form a catch group (Now we’ll understand why we created it).

That is, the regex /a([^a]*)$/ means:

  • the letter a
  • followed by zero or more characters that are not the letter a
  • followed by the end of the string

In other words, the regex takes the last a of the string, in addition to the characters that appear later, until the end of the string.

Characters that are not the letter a were placed in parentheses to form a catch group, because it is possible to use its value in the replace. So I don’t lose the information of what was after the a. And as this is the first pair of parentheses that appears in the regex, may I refer to it using the special variable $1:

let s = 'Uma string assim com várias letras a, mas só a última que é para substituir';

s = s.replace(/a([^a]*)$/, '@$1');
console.log(s);
// Uma string assim com várias letras a, mas só a última que é par@ substituir

Thus, the a followed by "anything that is not a" is replaced by @ followed by $1 (which are the same characters that existed after the a). With this, only the last a the string is exchanged, and the rest of the string remains the same.


Solution without regex

A solution without regex is also possible, using lastIndexOf to obtain the index of the latter a of the string, and then using substring to get the parts of the string before and after the a:

let s = 'Uma string assim com várias letras a, mas só a última que é para substituir';
let antiga = 'a';
let nova = '@';

var index = s.lastIndexOf(antiga);
// se encontrou a letra
if (index >= 0) {
    s = s.substring(0, index) + nova + s.substring(index + antiga.length);
}
console.log(s);
// Uma string assim com várias letras a, mas só a última que é par@ substituir

The first substring takes the entire chunk between the beginning of the string until the last occurrence of a. The second substring takes the whole stretch right after that a, to the end of the string. And between the two I put the new string (in case, @).


Regex versus substring

The solution with substring works very well with strings of any size. Example:

let s = 'teste 123 outro teste fim';
let antiga = 'teste';
let nova = 'abcde';

var index = s.lastIndexOf(antiga);
// se encontrou a letra
if (index >= 0) {
    s = s.substring(0, index) + nova + s.substring(index + antiga.length);
}
console.log(s);
// teste 123 outro abcde fim

If you are going to use regex, it is no use to use the above solution because the syntax [^...] (character class denied) only works for single characters. To check if an entire text is the last occurrence, we can use a Negative Lookahead, which is basically a way for the regex to check if something doesn’t exist ahead:

let s = 'teste 123 outro teste fim';
let antiga = 'teste';
let nova = 'abcde';

s = s.replace(new RegExp(antiga + '(?!.*' + antiga + '.*$)(.*?)$'), nova + '$1');
console.log(s);
// teste 123 outro abcde fim

In this case, the created regex is equivalent to teste(?!.*teste.*$)(.*?)$ (that is, the string teste, provided that there is no other occurrence of "test" until the end of the string). Then I keep capturing the rest of the string until the end, so I can have the variable $1 and use it on replace.

  • thanks a lot guys, the regex worked, and also using the substring and the lastIndexOf also worked, opened up my mind a lot, it was worth too

  • @iagomiranda If one of the answers solved your problem, you can choose the one that best solved and accept it, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem. Don’t forget that you can also vote in all the answers you found useful.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.