Multiple sequential replacement of strings between two indices

I have a long string 'str' and a list of triplets in the form [start, end, replace_str] . I need to iterate over a list of triplets and replace the content of 'str' between the start and end indexes of replace_str. The replace_str can be of variable length. The problem is that after the first replacement of the triplet, the contents and length of "str" ​​change, and the replacement with the next triplex start and end indices do not remain valid, and the replacement occurs in the wrong position.

eg. If a

str = 'I want to go to India.'

      

and a list of triplets

[3,7,'<span id="7">want</span>']

[11,13,'<span id="49">go</span>']

[1,2,'<span id="1003">I</span>']

      

After replacement with the first triplet, 'str' looks like this:

'I <span id="7">want</span> to go to India'.

      

Now for the second replacement of the triplet with start = 11 and end = 13 , str will look like this:

'I <span id<span id="49">go<span>>7">want</span> to go to India.'

      

whereas I want it to look like

'I <span id="7">want</span> to <span id="49">go<span> to India.'

      

How to handle such multiple sequential string replacements in javascript?

EDIT: https://stackoverflow.com/users/82548/david-thomas suggested my original question above is problem XY - problem with solution for another problem, not the actual problem. Thus, the actual problem arises here.

Beginning with:

str = 'I want to go to India.'

      

and a list of triplets

[3,7,'<span id="7">want</span>']

[11,13,'<span id="49">go</span>']

[1,2,'<span id="1003">I</span>']

      

I want to replace the content of str between start and end using replace_str so that my result string, after replacing all triplets, looks like this:

'<span id="1003">I<span> <span id="7">want</span> to <span id="49">go<span> to India.'

      

+3


source to share


2 answers


Assuming the replacement triplets never intersect, you can start at the end and go back to the beginning:

String.prototype.replaceBetween = function(start, end, what) {
    return this.substring(0, start) + what + this.substring(end);
};

var str = 'I want to go to India.'
var triplets = [
  [3,7,'<span id="7">want</span>']
, [11,13,'<span id="49">go</span>']
, [1,2,'<span id="1003">I</span>']
]

triplets.sort(function (a, b) {
  return b[0] - a[0]
})

for (var ii=0, triplet; triplet=triplets[ii]; ii++) {
  str = str.replaceBetween(triplet[0]-1, triplet[1], triplet[2])
}

console.log(str)
// <span id="1003">I</span><span id="7">want</span>to <span id="49">go</span>to India.

      



You can find the original post about the method replaceBetween()

here .

+3


source


You do not need to worry about shifting indices when replacing strings that appear later in the original string. To do this, you can sort the list of substitutions by their starting indices in reverse order:

function mreplace(str, repl) {
    repl.sort(function(a, b) {
        if (a[0] < b[0]) return 1;
        if (a[1] > b[1]) return -1;
        return 0;
    });

    for (var i = 0; i < repl.length; i++) {
        var begin = repl[i][0];
        var end = repl[i][1];
        var s = repl[i][2];

        str = str.substr(0, begin) + s + str.substr(end);
    }

    return str;
}

var str = mreplace("I want to go to India", [
    [2, 6, '<span id="7">want</span>'],
    [10, 12, '<span id="49">go</span>'],
    [0, 1, '<span id="1003">I</span>']
]);

console.log(str);

// "<span id="1003">I</span> <span id="7">want</span> to <span id="49">go</span> to India"

      



This snippet can have unpredictable results when two or more of the starting indices are the same. because Javascript's sorting algorithm is not necessarily stable, you must find other ways to enforce a specific replacement order. (You can make the sort stable by pushing the index of the original list on each triplet and use that as a secondary sort criterion.)

Note that I changed the start and end indices in your example so that they are null based, which is how indices work in Javascript. In my opinion, deviating from this index view creates a lot of confusion.

+3


source







All Articles