JavaScript:替换字符串中最后一次出现的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2729666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:41:22  来源:igfitidea点击:

JavaScript: replace last occurrence of text in a string

javascriptstringreplace

提问by Ruth

See my code snippet below:

请参阅下面的代码片段:

var list = ['one', 'two', 'three', 'four'];
var str = 'one two, one three, one four, one';
for ( var i = 0; i < list.length; i++)
{
     if (str.endsWith(list[i])
     {
         str = str.replace(list[i], 'finish')
     }
 }

I want to replace the last occurrence of the word one with the word finish in the string, what I have will not work because the replace method will only replace the first occurrence of it. Does anyone know how I can amend that snippet so that it only replaces the last instance of 'one'

我想用字符串中的单词完成替换最后一次出现的单词 one,我所拥有的将不起作用,因为替换方法只会替换它的第一次出现。有谁知道我如何修改该片段,使其仅替换“一个”的最后一个实例

回答by Pointy

Well, if the string really ends with the pattern, you could do this:

好吧,如果字符串真的以模式结尾,你可以这样做:

str = str.replace(new RegExp(list[i] + '$'), 'finish');

回答by T.J. Crowder

You can use String#lastIndexOfto find the last occurrence of the word, and then String#substringand concatenation to build the replacement string.

您可以使用String#lastIndexOf查找最后一次出现的单词,然后String#substring和连接来构建替换字符串。

n = str.lastIndexOf(list[i]);
if (n >= 0 && n + list[i].length >= str.length) {
    str = str.substring(0, n) + "finish";
}

...or along those lines.

...或沿着这些路线。

回答by Matt

I know this is silly, but I'm feeling creative this morning:

我知道这很愚蠢,但今天早上我觉得很有创意:

'one two, one three, one four, one'
.split(' ') // array: ["one", "two,", "one", "three,", "one", "four,", "one"]
.reverse() // array: ["one", "four,", "one", "three,", "one", "two,", "one"]
.join(' ') // string: "one four, one three, one two, one"
.replace(/one/, 'finish') // string: "finish four, one three, one two, one"
.split(' ') // array: ["finish", "four,", "one", "three,", "one", "two,", "one"]
.reverse() // array: ["one", "two,", "one", "three,", "one", "four,", "finish"]
.join(' '); // final string: "one two, one three, one four, finish"

So really, all you'd need to do is add this function to the String prototype:

所以实际上,您需要做的就是将此函数添加到 String 原型中:

String.prototype.replaceLast = function (what, replacement) {
    return this.split(' ').reverse().join(' ').replace(new RegExp(what), replacement).split(' ').reverse().join(' ');
};

Then run it like so: str = str.replaceLast('one', 'finish');

然后像这样运行它: str = str.replaceLast('one', 'finish');

One limitation you should know is that, since the function is splitting by space, you probablycan't find/replace anything with a space.

您应该知道的一个限制是,由于函数是按空格分割的,因此您可能无法找到/替换任何带有空格的内容。

Actually, now that I think of it, you could get around the 'space' problem by splitting with an empty token.

实际上,现在我想到了这一点,您可以通过用空标记拆分来解决“空间”问题。

String.prototype.reverse = function () {
    return this.split('').reverse().join('');
};

String.prototype.replaceLast = function (what, replacement) {
    return this.reverse().replace(new RegExp(what.reverse()), replacement.reverse()).reverse();
};

str = str.replaceLast('one', 'finish');

回答by WilsonCPU

Not as elegant as the regex answers above, but easier to follow for the not-as-savvy among us:

不像上面的正则表达式答案那么优雅,但对于我们中不那么精明的人来说更容易理解:

function removeLastInstance(badtext, str) {
    var charpos = str.lastIndexOf(badtext);
    if (charpos<0) return str;
    ptone = str.substring(0,charpos);
    pttwo = str.substring(charpos+(badtext.length));
    return (ptone+pttwo);
}

I realize this is likely slower and more wasteful than the regex examples, but I think it might be helpful as an illustration of how string manipulations can be done. (It can also be condensed a bit, but again, I wanted each step to be clear.)

我意识到这可能比正则表达式示例更慢且更浪费,但我认为它可能有助于说明如何完成字符串操作。(它也可以压缩一点,但同样,我希望每一步都清楚。)

回答by Irving

Thought I'd answer here since this came up first in my Google search and there's no answer (outside of Matt's creative answer :)) that generically replaces the last occurrence of a string of characters when the text to replace might not be at the end of the string.

我想我会在这里回答,因为这首先出现在我的谷歌搜索中,并且没有答案(除了马特的创意答案:))当要替换的文本可能不在最后时,一般会替换最后一次出现的字符串的字符串。

if (!String.prototype.replaceLast) {
    String.prototype.replaceLast = function(find, replace) {
        var index = this.lastIndexOf(find);

        if (index >= 0) {
            return this.substring(0, index) + replace + this.substring(index + find.length);
        }

        return this.toString();
    };
}

var str = 'one two, one three, one four, one';

// outputs: one two, one three, one four, finish
console.log(str.replaceLast('one', 'finish'));

// outputs: one two, one three, one four; one
console.log(str.replaceLast(',', ';'));

回答by mr.freeze

Here's a method that only uses splitting and joining. It's a little more readable so thought it was worth sharing:

这是一种仅使用拆分和连接的方法。它更具可读性,因此认为值得分享:

    String.prototype.replaceLast = function (what, replacement) {
        var pcs = this.split(what);
        var lastPc = pcs.pop();
        return pcs.join(what) + replacement + lastPc;
    };

回答by Tim Long

A simple answer without any regex would be:

没有任何正则表达式的简单答案是:

str = str.substr(0, str.lastIndexOf(list[i])) + 'finish'

回答by Pascut

If speed is important, use this:

如果速度很重要,请使用以下命令:

/**
 * Replace last occurrence of a string with another string
 * x - the initial string
 * y - string to replace
 * z - string that will replace
 */
function replaceLast(x, y, z){
    var a = x.split("");
    var length = y.length;
    if(x.lastIndexOf(y) != -1) {
        for(var i = x.lastIndexOf(y); i < x.lastIndexOf(y) + length; i++) {
            if(i == x.lastIndexOf(y)) {
                a[i] = z;
            }
            else {
                delete a[i];
            }
        }
    }

    return a.join("");
}

It's faster than using RegExp.

它比使用 RegExp 更快。

回答by Fusty

Couldn't you just reverse the string and replace only the first occurrence of the reversed search pattern? I'm thinking . . .

难道您不能只反转字符串并仅替换反转搜索模式的第一次出现吗?我在想 。. .

var list = ['one', 'two', 'three', 'four'];
var str = 'one two, one three, one four, one';
for ( var i = 0; i < list.length; i++)
{
     if (str.endsWith(list[i])
     {
         var reversedHaystack = str.split('').reverse().join('');
         var reversedNeedle = list[i].split('').reverse().join('');

         reversedHaystack = reversedHaystack.replace(reversedNeedle, 'hsinif');
         str = reversedHaystack.split('').reverse().join('');
     }
 }

回答by dario nascimento

Old fashioned and big code but efficient as possible:

老式的大代码,但尽可能高效:

function replaceLast(origin,text){
    textLenght = text.length;
    originLen = origin.length
    if(textLenght == 0)
        return origin;

    start = originLen-textLenght;
    if(start < 0){
        return origin;
    }
    if(start == 0){
        return "";
    }
    for(i = start; i >= 0; i--){
        k = 0;
        while(origin[i+k] == text[k]){
            k++
            if(k == textLenght)
                break;
        }
        if(k == textLenght)
            break;
    }
    //not founded
    if(k != textLenght)
        return origin;

    //founded and i starts on correct and i+k is the first char after
    end = origin.substring(i+k,originLen);
    if(i == 0)
        return end;
    else{
        start = origin.substring(0,i) 
        return (start + end);
    }
}