जावास्क्रिप्ट: एक स्ट्रिंग में पाठ की अंतिम घटना को प्रतिस्थापित करता है


97

नीचे मेरा कोड स्निपेट देखें:

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

मैं एक शब्द की अंतिम घटना को स्ट्रिंग में शब्द खत्म करने के साथ बदलना चाहता हूं, जो मेरे पास नहीं है वह काम नहीं करेगा क्योंकि प्रतिस्थापित विधि केवल इसकी पहली घटना को प्रतिस्थापित करेगी। क्या किसी को पता है कि मैं उस स्निपेट को कैसे संशोधित कर सकता हूं ताकि यह केवल 'एक' के अंतिम उदाहरण को बदल दे

जवाबों:


115

ठीक है, अगर स्ट्रिंग वास्तव में पैटर्न के साथ समाप्त होती है, तो आप ऐसा कर सकते हैं:

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

2
अच्छा विचार। पहले उस स्ट्रिंग से बचने की आवश्यकता है (हालांकि उसके नमूना डेटा के साथ नहीं, दी गई), जो गैर-तुच्छ है। :-(
टीजे क्राउडर

@ कोई संभावना नहीं! @ टीजे हाँ, वास्तव में यह सच है: रूथ यदि आप "शब्दों" के साथ समाप्त होते हैं, तो आप इसके लिए देख रहे हैं जिसमें नियमित अभिव्यक्तियों के लिए उपयोग किए जाने वाले विशेष वर्ण शामिल हैं, आपको उन लोगों से "बचने" की आवश्यकता होगी, जो टीजे कहते हैं कि थोड़ा मुश्किल है (हालांकि असंभव नहीं है)।
पोइंटी

क्या होगा अगर आप string2 के अंदर string1 के आखिरी रोकेस्ट को बदलना चाहते हैं?
सुपरयूपरड्यूपर

1
@SuperUberDuper अच्छी तरह से यह है अगर आप कुछ "/" वर्णों से घिरे मैच करना चाहते हैं। RegExp उदाहरण बनाने के दो तरीके हैं: कंस्ट्रक्टर ( new RegExp(string)), और इनलाइन सिंटैक्स ( /something/)। RegExp कंस्ट्रक्टर का उपयोग करते समय आपको "/" वर्णों की आवश्यकता नहीं होती है।
पॉइन्टी

3
आप "रक्षा" सभी regex के साथ अक्षरों से परे करने के लिए स्ट्रिंग के लिए एक परिवर्तन लागू करने के लिए होगा @TechLife ` - things like + , * , ? `, कोष्ठक, वर्ग कोष्ठक, हो सकता है अन्य बातों के।
पोइंट्टी

35

आप String#lastIndexOfशब्द की अंतिम घटना को खोजने के लिए उपयोग कर सकते हैं , और फिर String#substringप्रतिस्थापन स्ट्रिंग का निर्माण करने के लिए सहमति।

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

... या उन पंक्तियों के साथ।


1
एक अन्य उदाहरण: var nameSplit = item.name.lastIndexOf (","); if (nameSplit! = -1) item.name = item.name.substr (0, nameSplit) + "और" + item.name.substr (nameSplit + 2);
बेन गोटोव

22

मुझे पता है कि यह मूर्खतापूर्ण है, लेकिन मैं आज सुबह रचनात्मक महसूस कर रहा हूं:

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

11
@Alexander Uhhh, कृपया उत्पादन कोड में इसका उपयोग न करें ... या कोई भी कोड ... एक सरल regex पर्याप्त होगा।
थोड़ा सा

12

ऊपर के रूप में रेग्जेस जवाब के रूप में सुरुचिपूर्ण नहीं है, लेकिन हमारे बीच में नहीं-प्रेमी के लिए पालन करना आसान है:

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

मुझे लगता है कि यह संभावना धीमी है और रेगेक्स उदाहरणों की तुलना में अधिक बेकार है, लेकिन मुझे लगता है कि यह स्ट्रिंग हेरफेर कैसे किया जा सकता है इसका एक उदाहरण के रूप में सहायक हो सकता है। (इसे थोड़ा सा गाढ़ा भी किया जा सकता है, लेकिन फिर, मैं चाहता था कि प्रत्येक चरण स्पष्ट हो।)


9

यहां एक विधि है जो केवल विभाजन और जुड़ने का उपयोग करती है। यह थोड़ा अधिक पठनीय है इसलिए सोचा कि यह साझा करने लायक था:

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

यह अच्छी तरह से काम करता है, हालांकि यह स्ट्रिंग की शुरुआत के लिए प्रतिस्थापन जोड़ देगा अगर स्ट्रिंग doesn't में whatबिल्कुल शामिल नहीं है । जैसे'foo'.replaceLast('bar'); // 'barfoo'
१ .

8

मैंने सोचा कि मैं यहाँ उत्तर दूंगा क्योंकि यह मेरी 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(',', ';'));

4

बिना किसी रेगेक्स के एक सरल उत्तर होगा:

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

2
क्या होगा अगर मूल स्ट्रिंग में कोई घटना नहीं है?
टोमज़ाहलिन

सबसे स्वीकृत उत्तर मेरा ही परिणाम देता है! यहां परीक्षा परिणाम है:
टिम लॉन्ग

मेरा:> s = s.substr (0, s.lastIndexOf ('d')) + 'खत्म' => 'खत्म' ... उनका:> s = s.replace (नया RegExp ('d + +') $ '),' फिनिश ') =>' फिनिश '
टिम लॉन्ग

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

2

यदि गति महत्वपूर्ण है, तो इसका उपयोग करें:

/**
 * 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 का उपयोग करने से तेज है।


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

1

सरल समाधान प्रतिस्थापन विधि का उपयोग करना होगा। चूंकि स्ट्रिंग सूची तत्व के साथ समाप्त हो रही है, हम lastIndexOfपद्धति का उपयोग किए बिना स्ट्रिंग के लिए स्ट्रिंग का उपयोग कर सकते हैं

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


1

मुझे ऊपर का कोई भी उत्तर पसंद नहीं आया और नीचे के साथ आया

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

उम्मीद है की वो मदद करदे!


0

मैं प्रतिस्थापित-अंतिम 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>

यह स्ट्रिंग और रेगेक्स रिप्लेसमेंट के लिए काम करता है।


-1
str = (str + '?').replace(list[i] + '?', 'finish');

6
आम तौर पर, एक स्पष्टीकरण आम तौर पर उत्तर के अलावा चाहता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.