10

Is there a function that can replace a string within a string once at a specific index of the string? Example:

var string1="my text is my text and my big text";
var string2="my";
string1.replaceAt(string2,"your",2);

and the resultant output would be "my text is my text and your big text"

0

5 Answers 5

6

You can do this with a little bit of manipulation, not requiring any regex.

I used this function to fetch the position (index) of another string within a string.

From there, it's as simple as returning a substring from the beginning to the found index, injecting your replacement, and then returning the rest of the string.

function replaceAt(s, subString, replacement, index) {
  const p = s.split(subString, index+1).join(subString);
  return p.length < s.length ? p + replacement + s.slice(p.length + subString.length) : s;
}

console.log(replaceAt("my text is my text and my big text", "my", "your", 2))
console.log(replaceAt("my text is my text and that's all", "my", "your", 2))
console.log(replaceAt("my text is my my my my text", "my", "your", 2))

Sign up to request clarification or add additional context in comments.

3 Comments

@mplungjan The main issue with regex, is you're assuming that the substring doesn't contain any regexp characters that need escaping. This can cause some nasty bugs down the road, for some strings that may contain periods or stars. Additionally, to create a comparable function to your own, would require this escaping, and would slow things down considerably: jsperf.com/string-index-replacements
Which is good to know and handle when needed. There will be no need for performance checking for simple sporadid changing. If there is, then yes, one should handle that
always prefer str.slice(..) over str.substring(..) because it's more consistent (negative indexes, ..) and behave like arr.slice(..). str.substr(..) shouldn't be used as described
2

There's not a built-in way to do that, but you can exploit the fact that .replace() can be passed a function:

let count = 0;
console.log("my text is my text and my big text".replace(/my/g, function() {
  if (count++ === 2) return "your";
  return "my";
}));
The function is passed the matched string and any groups as arguments, but in this case that's not really necessary.

4 Comments

Missing a ) at the end
Wait what? Oh durr right, sorry I'll fix it. edit or somebody else will :) Thanks guys
Ok, and how I can make a function with parameters? string1.replace("my","your",2)
@itfreelance by using this, constructing a RegExp from the escaped input string, and wrapping the above into a function scope.
2

Here is a prototype version

String.prototype.replaceAt = function(str1,str2,pos) {
  let count = 0;
  let re = new RegExp(str1,"g");
  return this.replace(re, function() {
    return (count++ === pos) ? str2 : str1;
  });
}
console.log("my text is my text and my big text".replaceAt("my","your",2))

Comments

2

Beside the use of a function for replacement, you could use the given variable for the position directly for decrementing and take this value as check for replacement or not.

const replace = (string, s, r, p) => string.replace(new RegExp(s, 'g'), m => p-- ? m : r);
var string = 'my text is my text and my big text';

console.log(replace(string, 'my', 'your', 2));

Comments

1

As we need to look for index where we need to replace our word and for other words we don't need any change so used "map". Converted string to array by split and using map returned each element as it is and just replaced word when reached to specific index (by logic of index-- == 0). Finally joined back array to string.

    function replace(text, strFrom, strTo, index) {
    	return text.split(' ')
                   .map(d => d == strFrom && index-- == 0
                                 ? strTo 
                                 : d)
                   .join(' ')
    }
    
    var string = 'my text is my text and my big text';
    
    string = replace(string, 'my', 'your', 2)
    
    console.log(string)

1 Comment

Should try to use ===, as it's a bit more safe, and in this case can easily be swapped: eslint.org/docs/rules/eqeqeq

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.