2010-04-28 136 views
47

見我下面的代碼片段:的JavaScript:替換字符串文本中最後一次出現

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

我想用字符串中的字完成替換的單詞一個最後一次出現,我有什麼不會因爲替換方法只會取代它的第一次出現。有誰知道我可以修改該段,這樣,只替換「一」

回答

67

好吧,如果字符串真的與模式結束,你可以這樣做的最後一個實例:

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

好主意。首先需要轉義該字符串(儘管不是與她的示例數據一致),這是非平凡的。 :-( – 2010-04-28 13:13:02

+0

非常感謝你 – Ruth 2010-04-28 13:26:01

+0

@Ruth no prob!@TJ是的,事實的確如此:Ruth如果最終得到的是包含用於正則表達式的特殊字符的「詞」,則需要TJ說這是一個有點棘手的問題(雖然不是不可能) – Pointy 2010-04-28 21:56:41

30

你可以使用String#lastIndexOf查找單詞的最後一次出現,然後使用String#substring和串聯來構建替換字符串。

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

......或沿着這些線。

+0

非常感謝你 – Ruth 2010-04-28 13:25:24

+1

另一個例子:\t \t \t \t var nameSplit = item.name.lastIndexOf(「,」); \t \t \t \t如果(nameSplit = -1!) \t \t \t \t \t item.name = item.name.substr(0,nameSplit)+ 「和」 + item.name.substr(nameSplit + 2); – 2012-02-13 17:52:38

16

我知道這是愚蠢的,但我覺得這個創意早:

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

非常感謝您 – Ruth 2010-04-28 13:26:59

+1

您稱之爲無聊,我們稱它爲有幫助! – Alexander 2014-09-12 13:22:13

+7

@Alexander Uhhh,請不要在生產代碼中使用它...或者任何代碼...一個簡單的正則表達式就足夠了。 – Slight 2016-06-20 16:46:47

9

不一樣優雅與上述正則表達式的答案,但更容易執行的不是如精明的我們當中:

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

想到我會在這裏回答,因爲這在我的Google搜索中首先出現,並且沒有答案(除了Matt的創造性答案:)),通常取代最後一次出現的字符串,當要替換的文本可能不在字符串末尾時。

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

老式的和大的代碼,但儘可能高效:

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

你不能只是扭轉字符串,只替換逆轉搜索模式的第一次出現?我在想 。 。 。

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(''); 
    } 
} 
-1
str = (str + '?').replace(list[i] + '?', 'finish'); 
+6

通常,除了答案之外,通常還需要解釋 – 2015-02-12 23:44:00

3

下面是僅使用分裂和加入的方法。這是一個有點更具可讀性,從而認爲這是值得分享:

​​
1

如果速度是重要的,使用此:

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

這比使用正則表達式更快。

相關問題