См. Мой фрагмент кода ниже:
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 словом finish в строке, то, что у меня есть, не будет работать, потому что метод replace заменит только первое его вхождение. Кто-нибудь знает, как я могу изменить этот фрагмент, чтобы он заменял только последний экземпляр 'one'
new RegExp(string)
) и встроенный синтаксис (/something/
). При использовании конструктора RegExp символы «/» не нужны.` - things like
+,
*,
? `, Круглых скобок, квадратных скобок, может быть, других вещей.Вы можете использовать
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); }
Я понимаю, что это, вероятно, медленнее и расточительнее, чем примеры регулярных выражений, но я думаю, что это может быть полезно в качестве иллюстрации того, как можно выполнять строковые манипуляции. (Его также можно немного сжать, но опять же, я хотел, чтобы каждый шаг был ясным.)
источник
Вот метод, который использует только разделение и соединение. Это немного более читабельно, поэтому подумал, что стоит поделиться:
String.prototype.replaceLast = function (what, replacement) { var pcs = this.split(what); var lastPc = pcs.pop(); return pcs.join(what) + replacement + lastPc; };
источник
what
. eg'foo'.replaceLast('bar'); // 'barfoo'
Думал, что отвечу здесь, так как это появилось первым в моем поиске 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(',', ';'));
источник
Простой ответ без какого-либо регулярного выражения:
str = str.substr(0, str.lastIndexOf(list[i])) + '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(''); } }
источник
Если важна скорость, используйте это:
/** * 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.
источник
Простым решением было бы использовать метод подстроки. Поскольку строка заканчивается элементом списка, мы можем использовать string.length и вычислить конечный индекс для подстроки без использования
lastIndexOf
методаstr = str.substring(0, str.length - list[i].length) + "finish"
источник
Старомодный и объемный код, но максимально эффективный:
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); } }
источник
Мне не понравился ни один из приведенных выше ответов, и я предложил следующий
function replaceLastOccurrenceInString(input, find, replaceWith) { if (!input || !find || !replaceWith || !input.length || !find.length || !replaceWith.length) { // 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 npm.
var str = 'one two, one three, one four, one'; var result = replaceLast(str, 'one', 'finish'); console.log(result);
<script src="https://unpkg.com/replace-last@latest/replaceLast.js"></script>
Это работает для замены строк и регулярных выражений.
источник
str = (str + '?').replace(list[i] + '?', 'finish');
источник