جافا سكريبت: استبدال آخر ظهور للنص في سلسلة
انظر إلى مقطع الكود الخاص بي أدناه:
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 في السلسلة، ما لدي لن يعمل لأن طريقة الاستبدال ستستبدل أول ظهور لها فقط. هل يعرف أحد كيف يمكنني تعديل هذا المقتطف بحيث يستبدل آخر ظهور لكلمة 'one' فقط؟
الإجابة رقم 1
حسنًا، إذا كانت السلسلة تنتهي فعليًا بالنمط، يمكنك فعل هذا:
str = str.replace(new RegExp(list[i] + '$'), 'finish');
الإجابة رقم 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";
}
...أو على هذا النحو.
الإجابة رقم 3
ليس أنيقًا مثل الإجابات باستخدام التعبيرات النمطية أعلاه، لكنه أسهل للمتابعة بالنسبة لأولئك منا الذين ليسوا على دراية كبيرة:
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);
}
أدرك أن هذا من المحتمل أن يكون أبطأ وأكثر هدرًا من أمثلة التعبيرات النمطية، لكن أعتقد أنه قد يكون مفيدًا كمثال على كيفية إجراء تغييرات النصوص. (يمكن أيضًا تكثيفه قليلًا، لكن مرة أخرى، أردت أن يكون كل خطوة واضحة.)
الإجابة رقم 4
إليك طريقة تستخدم فقط تقسيم ودمج النصوص. إنها أكثر قابلية للقراءة قليلًا لذا اعتقدت أنه من المفيد مشاركتها:
String.prototype.replaceLast = function (what, replacement) {
var pcs = this.split(what);
var lastPc = pcs.pop();
return pcs.join(what) + replacement + lastPc;
};
الإجابة رقم 5
إجابة بسيطة في سطر واحد بدون أي تعبيرات قياسية ستكون:
str = str.substring(0, str.lastIndexOf(list[i])) + 'finish'
الإجابة رقم 6
حل النظر المسبق السلبي:
str.replace(/(one)(?!.*\1)/, 'finish')
توضيح مقدم من الموقع regex101.com,
/(one)(?!.*\1)/المجموعة الملتقطة الأولى (واحد)
one- يطابق الأحرف one حرفيًا (حساس لحالة الأحرف)
النظرة المستقبلية السلبية (?!.*\1)
تأكد من أن التعبير النمطي أدناه لا يتطابق
.يطابق أي حرف (باستثناء محددات نهاية السطر)*يطابق الرمز السابق بين صفر وعدد غير محدود من المرات، أكبر عدد ممكن من المرات، مع إعادة ما يلزم (جشع)\1يطابق نفس النص الذي تم مطابقته مؤخرًا بواسطة المجموعة الأولى التي تلتقط
الإجابة رقم 7
ظننت أنه من الأفضل أن أجيب هنا لأن هذا ظهر أولاً في بحثي على 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(',', ';'));
