请参阅下面的代码片段:
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')
}
}
我想用字符串中的单词完成替换单词 one 的最后一次出现,我所拥有的将不起作用,因为 replace 方法只会替换它的第一次出现。有谁知道我如何修改该片段,使其仅替换“一个”的最后一个实例
好吧,如果字符串真的以模式结尾,你可以这样做:
str = str.replace(new RegExp(list[i] + '$'), 'finish');
您可以使用 String#lastIndexOf
查找单词的最后一次出现,然后使用 String#substring
和连接来构建替换字符串。
n = str.lastIndexOf(list[i]);
if (n >= 0 && n + list[i].length >= str.length) {
str = str.substring(0, n) + "finish";
}
...或沿着这些路线。
我知道这很愚蠢,但今天早上我感觉很有创意:
'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 原型中:
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');
不像上面的正则表达式回答那么优雅,但对于我们中间不那么精明的人来说更容易理解:
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);
}
我意识到这可能比正则表达式示例更慢且更浪费,但我认为它可能有助于说明如何进行字符串操作。 (它也可以压缩一点,但我希望每一步都清楚。)
以为我会在这里回答,因为这首先出现在我的谷歌搜索中,并且没有答案(除了马特的创造性答案:)),当要替换的文本可能不在末尾时,通常会替换最后出现的字符串的字符串。
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(',', ';'));
这是一种只使用拆分和连接的方法。它更具可读性,因此认为值得分享:
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'
没有任何正则表达式的简单答案是:
str = str.substr(0, str.lastIndexOf(list[i])) + 'finish'
我不喜欢上面的任何答案并想出了以下答案
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
希望有帮助!
如果速度很重要,请使用:
/**
* 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 更快。
简单的解决方案是使用 substring 方法。由于字符串以列表元素结尾,我们可以使用 string.length 并计算子字符串的结束索引,而无需使用 lastIndexOf
方法
str = str.substring(0, str.length - list[i].length) + "finish"
难道你不能只反转字符串并只替换第一次出现的反转搜索模式吗?我在想 。 . .
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('');
}
}
老式且大代码但尽可能高效:
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);
}
}
我建议使用 replace-last npm 包。
var str = '一二,一三,一四,一'; var result = replaceLast(str, 'one', 'finish');控制台.log(结果);
这适用于字符串和正则表达式替换。
function replaceLast(text, searchValue, replaceValue) {
const lastOccurrenceIndex = text.lastIndexOf(searchValue)
return `${
text.slice(0, lastOccurrenceIndex)
}${
replaceValue
}${
text.slice(lastOccurrenceIndex + searchValue.length)
}`
}
str = (str + '?').replace(list[i] + '?', 'finish');
new RegExp(string)
) 和内联语法 (/something/
)。使用 RegExp 构造函数时不需要“/”字符。` - things like
+,
*,
?`、括号、方括号或其他内容“保护”所有正则表达式元字符。