两个索引之间的多个顺序字符串替换

时间:2015-05-22 05:00:35

标签: javascript string algorithm replace

我有一个很长的字符串' str' 以及 [start,end,replace_str] 形式的三元组列表。我需要遍历三元组列表,并用replace_str替换开始和结束索引之间的' str' 的内容。 replace_str字符串可以是可变长度的。问题是,在第一次三联体更换后,' str的内容和长度。得到改变,下一个三联的开始和结束指数的替换不会保持有效,更换发生在错误的位置。

e.g。如果

str = 'I want to go to India.'

和三元组列表是

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

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

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

用第一个三联体替换后,&#39; str&#39;看起来像:

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

现在,对于 start = 11 end = 13 进行第二次三联替换,str将如下所示:

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

虽然我希望它看起来像

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

如何在javascript中处理这样的多个连续字符串替换?

编辑: https://stackoverflow.com/users/82548/david-thomas建议我上面的原始问题是XY问题 - 解决另一个问题而不是实际问题的问题。所以这就是实际问题。

从:

开始
str = 'I want to go to India.'

和三元组列表是

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

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

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

我想用 replace_str 替换 start end 之间 str 的内容,以便我的结果字符串,在更换所有三胞胎后,将如下所示:

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

2 个答案:

答案 0 :(得分:3)

当您首先替换原始字符串中稍后出现的字符串时,您不必担心转移索引。为此,您可以按相反的顺序按其起始索引对替换列表进行排序:

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"

当两个或多个起始索引相同时,此代码段可能会产生不可预测的结果。因为Javascript的排序算法不一定稳定,你必须找到其他方法来确保定义的替换顺序。 (您可以通过将原始列表索引推送到每个三元组并将其用作二级排序标准来使排序稳定。)

请注意,我已经更改了示例中的开始和结束索引,因此它们是从零开始的,这就是Javascript中索引的工作方式。在我看来,偏离这个索引表示会产生很多混乱。

答案 1 :(得分:3)

假设替换三元组从不重叠,那么你可以从最后开始并回到开头:

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.

您可以找到有关replaceBetween()技术here的原始帖子。