9

I have a problem with replacing last word in JS, I am still searching solution but i cannot get it.

I have this code:

var string = $(element).html(); // "abc def abc xyz"
var word   = "abc";
var newWord = "test";

var newV   = string.replace(new RegExp(word,'m'), newWord);

I want replace last word "abc" in this string, but now I can only replace all or first occurrence in string. How can I do this? Maybe is not good way?

Bucket
  • 7,415
  • 9
  • 35
  • 45
Beniamin
  • 550
  • 1
  • 4
  • 13

7 Answers7

26

Here is an idea ....

This is a case-sensitive string search version

var str = 'abc def abc xyz';
var word = 'abc';
var newWord = 'test';

// find the index of last time word was used
// please note lastIndexOf() is case sensitive
var n = str.lastIndexOf(word);

// slice the string in 2, one from the start to the lastIndexOf
// and then replace the word in the rest
str = str.slice(0, n) + str.slice(n).replace(word, newWord);
// result abc def test xyz

If you want a case-insensitive version, then the code has to be altered. Let me know and I can alter it for you. (PS. I am doing it so I will post it shortly)

Update: Here is a case-insensitive string search version

var str = 'abc def AbC xyz';
var word = 'abc';
var newWord = 'test';

// find the index of last time word was used
var n = str.toLowerCase().lastIndexOf(word.toLowerCase());

// slice the string in 2, one from the start to the lastIndexOf
// and then replace the word in the rest
var pat = new RegExp(word, 'i')
str = str.slice(0, n) + str.slice(n).replace(pat, newWord);
// result abc def test xyz

N.B. Above codes looks for a string. not whole word (ie with word boundaries in RegEx). If the string has to be a whole word, then it has to be reworked.

Update 2: Here is a case-insensitive whole word match version with RegEx

var str = 'abc def AbC abcde xyz';
var word = 'abc';
var newWord = 'test';

var pat = new RegExp('(\\b' + word + '\\b)(?!.*\\b\\1\\b)', 'i');
str = str.replace(pat, newWord);
// result abc def test abcde xyz

Good luck :)

erosman
  • 7,094
  • 7
  • 27
  • 46
8
// create array
var words = $(element).html().split(" ");

// find last word and replace it
words[words.lastIndexOf("abc")] = newWord 

// put it back together
words = words.join(" ");
bobthedeveloper
  • 3,733
  • 2
  • 15
  • 31
3

You can use lookahead to get last word in a sentence:

var string = "abc def abc xyz";
var repl = string.replace(/\babc\b(?!.*?\babc\b)/, "test");
//=> "abc def test xyz"
anubhava
  • 761,203
  • 64
  • 569
  • 643
3

You want to both:

  • match abc
  • check that there isn't another abc afterward in the string

So you can use:

abc(?!.*abc)

(?!...) is a negative lookahead, it will fail the whole regex match if what's inside the lookahead is matched.

Also be careful as this would match abc in abcdaire: if you only want abc as a separate word you need to add word boundaries \b:

\babc\b(?!.*\babc\b)
Robin
  • 9,415
  • 3
  • 34
  • 45
  • for some reason `string.replace(/\babc\b(?!.*\babc\b)/, '')` replaces the last abc with a space, do you know why? http://jsfiddle.net/5q9K8/11/ – fiction Apr 17 '14 at 15:18
  • It really shouldn't... This is not just because since you deleted a word, the spaces on the left and right side are now adjacent? – Robin Apr 17 '14 at 15:21
  • haha yes it's exactly because of that, i'm stupid. well, good answer then – fiction Apr 17 '14 at 15:33
1

I'm not too familiar with JavaScript but you can probably twist this to fit your needs:

(\b\w+\b)(.*)(\1) replace with \1\2+'your_key_word'

See the demo to see what I mean.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
sshashank124
  • 31,495
  • 9
  • 67
  • 76
1

try

var string = $(element).html(); // "abc def abc xyz"
var word   = "abc";
var newWord = "test";

var newV   = string.replace(new RegExp(word+'$'), newWord);
webduvet
  • 4,220
  • 2
  • 28
  • 39
0

You can use the fact that the replace method replaces only the first occurrence of the target string if used without the global flag, and try something like:

"abc def abc xyz abc jkl".split(' ').reverse().join(' ').replace('abc', 'test').split(' ').reverse().join(' ')

tewathia
  • 6,890
  • 3
  • 22
  • 27