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

Posted

技术标签:

【中文标题】JavaScript:替换字符串中最后一次出现的文本【英文标题】:JavaScript: replace last occurrence of text in a string 【发布时间】:2011-02-13 08:28:24 【问题描述】:

在下面查看我的代码 sn-p:

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')
     
 

我想用字符串中的单词finish替换单词one的最后一次出现,我所拥有的将不起作用,因为replace方法只会替换它的第一次出现。有谁知道我可以如何修改那个 sn-p 以便它只替换 'one' 的最后一个实例

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

好主意。需要首先转义该字符串(尽管不使用她的示例数据,但已获准),这并非易事。 :-( @Ruth 没有问题! @TJ 是的,确实是这样:Ruth 如果你最终得到了你正在寻找的“单词”,其中包括用于正则表达式的特殊字符,你需要“转义”那些,正如 TJ 所说,这有点棘手(虽然不是不可能)。 如果要替换 string2 中最后出现的 string1 怎么办? @SuperUberDuper 好吧,如果你想匹配被“/”字符包围的东西。有两种方法可以创建 RegExp 实例:构造函数 (new RegExp(string)) 和内联语法 (/something/)。使用 RegExp 构造函数时不需要“/”字符。 @TechLife 你必须对字符串应用一个转换来“保护”所有带有` - things like +, *, ?`、括号、方括号的正则表达式元字符其他事情。【参考方案2】:

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

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

...或沿着这些思路。

【讨论】:

另一个例子:var nameSplit = item.name.lastIndexOf(", "); if (nameSplit != -1) item.name = item.name.substr(0, nameSplit) + " 和 "+ item.name.substr(nameSplit + 2);【参考方案3】:

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

'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"

真的,您需要做的就是将此函数添加到字符串原型中:

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

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

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

实际上,现在我想到了,您可以通过使用空令牌拆分来解决“空间”问题。

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');

【讨论】:

@Alexander Uhhh,请不要在生产代码中使用它......或任何代码......一个简单的正则表达式就足够了。 我认为未来的开发人员不太支持此代码。我认为已经达到了链接限制。【参考方案4】:

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

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);

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

它工作得很好,但是如果字符串根本不包含what,它会在字符串的开头添加替换。例如'foo'.replaceLast('bar'); // 'barfoo' 请避免原型污染。【参考方案6】:

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

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(',', ';'));

【讨论】:

【参考方案7】:

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

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

【讨论】:

原字符串没有出现怎么办? 最被接受的答案返回与我相同的结果!这是测试结果: 我的:> s = s.substr(0, s.lastIndexOf('d')) + 'finish' => 'finish' ... 他们的:> s = s.replace(new RegExp('d' + '$'), 'finish') => 'finish'【参考方案8】:

我不喜欢上面的任何答案,并想出了下面的答案

function isString(variable)  
    return typeof (variable) === 'string'; 


function replaceLastOccurrenceInString(input, find, replaceWith) 
    if (!isString(input) || !isString(find) || !isString(replaceWith)) 
        // returns input on invalid arguments
        return input;
    

    const lastIndex = input.lastIndexOf(find);
    if (lastIndex < 0) 
        return input;
    

    return input.substr(0, lastIndex) + replaceWith + input.substr(lastIndex + find.length);


用法:

const input = 'ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty';
const find = 'teen';
const replaceWith = 'teenhundred';

const output = replaceLastOccurrenceInString(input, find, replaceWith);
console.log(output);

// output: ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteenhundred twenty

希望有帮助!

【讨论】:

【参考方案9】:

如果速度很重要,请使用:

/**
 * 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("");

它比使用 RegExp 更快。

【讨论】:

【参考方案10】:

简单的解决方案是使用 substring 方法。 由于字符串以列表元素结尾,我们可以使用 string.length 并计算子字符串的结束索引,而无需使用 lastIndexOf 方法

str = str.substring(0, str.length - list[i].length) + "finish"

【讨论】:

【参考方案11】:

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

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('');
     
 

【讨论】:

【参考方案12】:

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

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);
    

【讨论】:

【参考方案13】:

我建议使用replace-last npm 包。

var str = 'one two, one three, one four, one';
var result = replaceLast(str, 'one', 'finish');
console.log(result);
&lt;script src="https://unpkg.com/replace-last@latest/replaceLast.js"&gt;&lt;/script&gt;

这适用于字符串和正则表达式替换。

【讨论】:

【参考方案14】:

这种方式对我有用。看看replace last character in string javascript

str.replace(/one([^one]*$)/, 'finish$1')

【讨论】:

【参考方案15】:
function replaceLast(text, searchValue, replaceValue) 
  const lastOccurrenceIndex = text.lastIndexOf(searchValue)
  return `$
      text.slice(0, lastOccurrenceIndex)
    $
      replaceValue
    $
      text.slice(lastOccurrenceIndex + searchValue.length)
    `

【讨论】:

【参考方案16】:
str = (str + '?').replace(list[i] + '?', 'finish');

【讨论】:

通常情况下,除了答案之外,通常还需要解释

以上是关于JavaScript:替换字符串中最后一次出现的文本的主要内容,如果未能解决你的问题,请参考以下文章

替换字符串中最后一次出现的字符串

如何使用javascript替换字符串中最后出现的字符

使用 sed 替换字符串中最后一次出现的字符

使用 sed 替换字符串中最后一次出现的字符

用另一个字符串替换第一次和最后一次出现的字符串

JavaScript重点记忆