javascript - कैसे जावास्क्रिप्ट में एक स्ट्रिंग के सभी घटनाओं को बदलने के लिए?


मेरे पास यह स्ट्रिंग है:

"Test abc test test abc test test test abc test test abc"

करते हुए

str = str.replace('abc', '');

केवल ऊपर की स्ट्रिंग में abc की पहली घटना को हटाते हुए लगता है मैं इसे सभी घटनाओं की जगह कैसे कर सकता हूं?



Answers



पूर्णता के लिए, मुझे यह सोचने के लिए मिला है कि मुझे यह करने के लिए किस पद्धति का उपयोग करना चाहिए। मूल रूप से ऐसा करने के दो तरीके हैं जैसा कि इस पृष्ठ पर अन्य उत्तरों द्वारा सुझाए गए हैं।

नोट: सामान्य रूप से, जावास्क्रिप्ट में अंतर्निहित प्रोटोटाइप का विस्तार आम तौर पर अनुशंसित नहीं है। स्ट्रिंग प्रोटोटाइप में स्ट्रिंग पर एक काल्पनिक मानक विधि के विभिन्न कार्यान्वयन दिखाते हुए, उदाहरण के लिए मैं स्ट्रिंग प्रोटोटाइप पर एक्सटेंशन के रूप में प्रदान कर रहा हूं।

नियमित अभिव्यक्ति आधारित कार्यान्वयन

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

भाजित और जुड़ें (कार्यात्मक) कार्यान्वयन

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

कार्यक्षमता के संदर्भ में पर्दे के पीछे नियमित अभिव्यक्ति कैसे काम करती है, इसके बारे में बहुत ज्यादा जानकारी नहीं होने के कारण, मैं प्रदर्शन के बारे में सोचने के बिना, विभाजन के प्रति झुकाव और अतीत में कार्यान्वयन में शामिल हो गया। जब मुझे आश्चर्य हुआ कि कौन अधिक कुशल था, और किस मार्जिन से मैंने इसका पता लगाने का एक बहाना इस्तेमाल किया

मेरे क्रोम विंडोज 8 मशीन पर, नियमित अभिव्यक्ति आधारित कार्यान्वयन सबसे तेज है , विभाजन के साथ और कार्यान्वयन में शामिल होने से 53% धीमा हो रहा है । नियमित अभिव्यक्ति का मतलब है कि मैं इस्तेमाल किए जाने वाले लैरेम इप्सम इनपुट के लिए दो बार दोगुनी हो।

इन दो कार्यान्वयनों को एक-दूसरे के विरुद्ध चलते हुए इस बेंचमार्क को देखें

जैसा कि नीचे टिप्पणी में @ थॉमस लैडुक और अन्य लोगों द्वारा किया गया है, नियमित अभिव्यक्ति आधारित कार्यान्वयन के साथ कोई समस्या हो सकती है यदि search में कुछ वर्ण हैं जो नियमित अभिव्यक्तियों में विशेष वर्ण के रूप में आरक्षित हैं। कार्यान्वयन यह मानता है कि कॉलर पहले से स्ट्रिंग से बच जाएगा या केवल तारों को पारित करेंगे जो नियमित अभिव्यक्तियों (MDN) में तालिका में वर्णों के बिना हैं।

एमडीएन हमारे तारों से बचने के लिए एक कार्यान्वयन भी प्रदान करता है यह अच्छा होगा यदि यह RegExp.escape(str) रूप में भी मानकीकृत है, लेकिन अफसोस, यह मौजूद नहीं है:

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

हम अपने String.prototype.replaceAll कार्यान्वयन के भीतर escapeRegExp के लिए कॉल कर सकते हैं, हालांकि, मुझे यकीन नहीं है कि यह प्रदर्शन को कैसे प्रभावित करेगा (संभवतः स्ट्रिंग्स के लिए भी, जिसकी बचने की आवश्यकता नहीं है, जैसे सभी अल्फ़ान्यूमेरिक स्ट्रिंग्स)।




str = str.replace(/abc/g, '');

टिप्पणी के जवाब में:

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

अपवोट की टिप्पणी को क्लिक करने के जवाब में, आप इसे और भी सरल बना सकते हैं:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(find, 'g'), replace);
}

नोट: नियमित अभिव्यक्ति में विशेष (मेटा) वर्ण होते हैं, और जैसा कि उन वर्णों से बचने के लिए पूर्व-प्रसंस्करण के बिना उपरोक्त find फ़ंक्शन में एक आक्षेप को अंधाधुंध रूप से पारित करने के लिए खतरनाक होता है यह मोज़िला डेवलपर नेटवर्क के जावास्क्रिप्ट गाइड पर नियमित अभिव्यक्तियों में शामिल है , जहां वे निम्न उपयोगिता कार्य प्रस्तुत करते हैं:

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

तो सुरक्षित से ऊपर सभी replaceAll() फ़ंक्शन को बनाने के लिए, यदि आप escapeRegExp शामिल escapeRegExp हैं, तो इसे निम्न में संशोधित किया जा सकता है:

function replaceAll(str, find, replace) {
    return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}



नोट: वास्तविक कोड में इसका उपयोग न करें।

एक सरल शाब्दिक स्ट्रिंग के लिए नियमित अभिव्यक्ति के विकल्प के रूप में, आप उपयोग कर सकते हैं

str = "Test abc test test abc test...".split("abc").join("");

सामान्य पैटर्न है

str.split(search).join(replacement)

इसे replaceAll और एक नियमित अभिव्यक्ति की तुलना में कुछ मामलों में तेज़ी से किया जाता था, लेकिन ऐसा आधुनिक ब्राउज़र में अब और नहीं लगता है। इसलिए, वास्तविक कोड में नहीं, नियमित अभिव्यक्ति से बचने की आवश्यकता से बचने के लिए यह केवल एक त्वरित हैक के रूप में इस्तेमाल किया जाना चाहिए।




g ध्वज सेट के साथ एक नियमित अभिव्यक्ति का उपयोग करना सभी को बदल देगा:

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

यहाँ भी देखें




स्वीकृत उत्तर के आधार पर यहां स्ट्रिंग प्रोटोटाइप फ़ंक्शन है:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

संपादित करें

यदि आपके find में विशेष वर्ण होंगे तो आपको उन्हें बचाना होगा:

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

बेला: http://jsfiddle.net/cdbzL/




अद्यतन करें:

यह अद्यतन के लिए कुछ हद तक देर हो चुकी है, लेकिन जब से मैं इस प्रश्न पर केवल ठोकर खाई, और पाया कि मेरा पिछला उत्तर एक नहीं है, मैं इससे खुश हूं। चूंकि एक ही शब्द को बदलने में सवाल शामिल था, इसलिए यह अविश्वसनीय है कि शब्द सीमाओं ( \b )

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

यह एक सरल regex है जो अधिकांश मामलों में शब्दों के कुछ हिस्सों को बदलने से बचा जाता है। हालांकि, एक डैश - अब भी एक शब्द सीमा माना जाता है। इसलिए इस स्थिति में cool-cat बॉल का उपयोग cool-cat जैसी तारों को बदलने से रोकने के लिए किया जा सकता है:

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

मूल रूप से, यह सवाल यहाँ के प्रश्न के समान है: जावास्क्रिप्ट को "'" के साथ "' '' '

@ माइक, मैंने वहां दिए गए उत्तर की जांच करें ... regexp एक subsrting के कई घटनाओं को बदलने का एकमात्र तरीका नहीं है, इसके दूर से। लचीला सोचो, विभाजन लगता है!

var newText = "the cat looks like a cat".split('cat').join('dog');

वैकल्पिक रूप से, शब्दों के भागों को बदलने से रोकने के लिए- जो अनुमोदित उत्तर भी करेंगे, भी! आप नियमित अभिव्यक्ति का उपयोग करते हुए इस मुद्दे को प्राप्त कर सकते हैं, मैं स्वीकार करता हूं, कुछ और अधिक जटिल और उसके परिणामस्वरूप, एक बालक धीमा भी है:

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

आउटपुट, इस स्ट्रिंग पर / cat / g अभिव्यक्ति का उपयोग करते हुए, स्वीकार्य उत्तर के समान है:

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

ओह वास्तव में, यह संभवत: वह नहीं है जो आप चाहते हैं। तो क्या है? आईएमएचओ, एक regex जो केवल 'बिल्ली' की बजाय कथित रूप से बदलता है (यानी किसी शब्द का हिस्सा नहीं), ऐसा ही है:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

मेरा अनुमान है, यह आपकी आवश्यकताओं को पूरा करता है यह पूरी तरह से निपुण नहीं है, लेकिन आपको इसे शुरू करने के लिए पर्याप्त होना चाहिए। मैं इन पृष्ठों पर कुछ और पढ़ना चाहूंगा यह आपकी विशिष्ट ज़रूरतों को पूरा करने के लिए इस अभिव्यक्ति को पूर्ण करने में उपयोगी साबित होगा।

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info

अंतिम अतिरिक्त:

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

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar



एक वैश्विक नियमित अभिव्यक्ति के खिलाफ मैच:

anotherString = someString.replace(/cat/g, 'dog');



str = str.replace(/abc/g, '');

या यहाँ से सभी फ़ंक्शन को प्रतिस्थापित करने का प्रयास करें:

उपयोगी जावास्क्रिप्ट विधियाँ जो अंतर्निहित ऑब्जेक्ट्स का विस्तार करती हैं?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

संपादित करें: प्रतिस्थापन के बारे में स्पष्टीकरणसभी उपलब्धता

स्ट्रिंग के प्रोटोटाइप में 'प्रतिस्थापन सभी' विधि जोड़ दी गई है। इसका मतलब यह है कि यह सभी स्ट्रिंग ऑब्जेक्ट / लिटरल्स के लिए उपलब्ध होगा।

उदाहरण के लिए

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'



नियमित अभिव्यक्ति का उपयोग करें:

str.replace(/abc/g, '');



यह सबसे तेज़ संस्करण है जो नियमित अभिव्यक्तियों का उपयोग नहीं करता है

संशोधित जेस्परफ़

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

विभाजन के रूप में लगभग दो बार तेज़ी से और विधि में जुड़ जाते हैं

जैसा कि यहां एक टिप्पणी में बताया गया है, यदि आपकी omit चर में place , तो यह काम नहीं करेगा, जैसा कि: सभी replaceAll("string", "s", "ss") , क्योंकि यह हमेशा शब्द की दूसरी घटना को बदलने में सक्षम होगा ।

मेरी पुनरावर्ती जगहों पर भिन्न रूपों के साथ एक और jsperf भी है जो इसे और भी तेज़ हो जाता है ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • जुलाई 27, 2017 को अपडेट करें: ऐसा लगता है कि हाल ही में जारी किए गए क्रोम 59 में रेगएक्सपी का अब तक का सबसे तेज प्रदर्शन है।



// लूप, जब तक कि संख्या की संख्या 0 पर नहीं आती है। या बस कॉपी / पेस्ट करें

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }



कहें कि आप 'एबी' के साथ सभी 'एबीसी' को बदलना चाहते हैं:

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

स्ट्रिंग प्रोटोटाइप को संशोधित करने से मैं कुछ और सोचा था।




सरल...

सिंगल उद्धरणों की जगह:

function JavaScriptEncode(text){
    text = text.replace(/'/g,''')
    // More encode here if required

    return text;
}



function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}






अगर आप जो ढूंढना चाहते हैं वह पहले से ही एक स्ट्रिंग में है, और आपके पास एक regex escaper नहीं है, तो आप जुड़ें / विभाजन का उपयोग कर सकते हैं:

function replaceMulti(haystack, needle, replacement)
{
    return haystack.split(needle).join(replacement);
}

someString = 'the cat looks like a cat';
anotherString = replaceMulti(someString, 'cat', 'dog');



मुझे यह विधि पसंद है (यह थोड़ा साफ दिखता है):

text = text.replace(new RegExp("cat","g"), "dog"); 



while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}



यदि आप यह सुनिश्चित करने का प्रयास कर रहे हैं कि आप जिस स्ट्रिंग की तलाश कर रहे हैं वह प्रतिस्थापन के बाद भी मौजूद नहीं रहेगी, आपको एक लूप का उपयोग करना होगा।

उदाहरण के लिए:

var str = 'test aabcbc';
str = str.replace(/abc/g, '');

पूरा होने पर, आपके पास अभी भी 'परीक्षण एबीसी' होगा!

यह हल करने के लिए सरलतम लूप होगा:

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

लेकिन यह प्रत्येक चक्र के लिए दो बार प्रतिस्थापन चलाता है शायद (नीचे मतदान के जोखिम पर) जो थोड़ी अधिक कुशल लेकिन कम पठनीय रूप के लिए जोड़ा जा सकता है:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

डुप्लिकेट तार की तलाश करते समय यह विशेष रूप से उपयोगी हो सकता है
उदाहरण के लिए, यदि हमारे पास 'a ,,, b' है और हम सभी डुप्लिकेट अल्पविराम को हटाना चाहते हैं।
[उस मामले में, कोई भी कर सकता है। फिर से (/, + / जी, ','), लेकिन कुछ बिंदु पर रीजेक्स जटिल हो जाता है और इसके बजाय लूप को धीमा होता है।]




आप बस नीचे विधि का उपयोग कर सकते हैं

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};



हालांकि लोगों ने रेगेक्स के उपयोग का उल्लेख किया है लेकिन यदि आप पाठ के मामले की परवाह किए बिना पाठ को बदलना चाहते हैं, तो बेहतर दृष्टिकोण है। अपरकेस या लोअरकेस की तरह वाक्यविन्यास के नीचे का प्रयोग करें

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

आप यहाँ विस्तृत उदाहरण का उल्लेख कर सकते हैं।




बस जोड़ें /g

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

सेवा मेरे

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/g मतलब वैश्विक है




निम्नलिखित फ़ंक्शन मेरे लिए काम करती है:

String.prototype.replaceAllOccurence = function(str1, str2, ignore) 
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
} ;

अब इस तरह के कार्यों को कॉल करें:

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

बस इस कोड को कॉपी और अपने ब्राउज़र कंसोल में टेस्ट पेस्ट करें।




मेरा क्रियान्वयन, बहुत आत्म व्याख्यात्मक

function replaceAll(string, token, newtoken) {
    if(token!=newtoken)
    while(string.indexOf(token) > -1) {
        string = string.replace(token, newtoken);
    }
    return string;
}



मैं पिछले रिकर्सन प्रतिस्थापन से परिणाम को स्टोर करने के लिए पी का उपयोग करता हूं:

function replaceAll(s, m, r, p) {
    return s === p || r.contains(m) ? s : replaceAll(s.replace(m, r), m, r, s);
}

यह स्ट्रिंग में सभी घटनाओं को बदल देगा जब तक कि यह संभव न हो:

replaceAll('abbbbb', 'ab', 'a')  'abbbb'  'abbb'  'abb'  'ab'  'a'

अनन्त लूप से बचने के लिए, मैं जांचता हूं कि प्रतिस्थापन r में मैच मिला है:

replaceAll('abbbbb', 'a', 'ab')  'abbbbb'



एक यूआरएल को एनकोड करने के लिए ज्यादातर लोग ऐसा कर रहे हैं। एक यूआरएल को सांकेतिकृत करने के लिए, आपको केवल रिक्त स्थान पर विचार नहीं करना चाहिए, बल्कि पूरे स्ट्रिंग को ठीक से encodeURI कनवर्ट करना चाहिए।

encodeURI("http://www.google.com/a file with spaces.html")

लेना:

http://www.google.com/a%20file%20with%20spaces.html



अगर स्ट्रिंग में समान पीटर जैसे abccc उपयोग का उपयोग होता है:

str.replace(/abc(\s|$)/g,"")



सभी प्रकार के वर्णों को बदलने के लिए, इस कोड का प्रयास करें:

Suppose we have need to send " and \ in my string, then we will convert it " to \" and \ to \\

तो यह विधि इस मुद्दे को हल करेगी।

String.prototype.replaceAll = function (find, replace) {
     var str = this;
     return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
 };

var message = $('#message').val();
             message = message.replaceAll('\\', '\\\\'); /*it will replace \ to \\ */
             message = message.replaceAll('"', '\\"');   /*it will replace " to \\"*/

मैं अजाक्स का उपयोग कर रहा था, और मुझे JSON प्रारूप में पैरामीटर भेजने की आवश्यकता थी। फिर मेरी विधि इस तरह दिख रही है:

 function sendMessage(source, messageID, toProfileID, userProfileID) {

     if (validateTextBox()) {
         var message = $('#message').val();
         message = message.replaceAll('\\', '\\\\');
         message = message.replaceAll('"', '\\"');
         $.ajax({
             type: "POST",
             async: "false",
             contentType: "application/json; charset=utf-8",
             url: "services/WebService1.asmx/SendMessage",
             data: '{"source":"' + source + '","messageID":"' + messageID + '","toProfileID":"' + toProfileID + '","userProfileID":"' + userProfileID + '","message":"' + message + '"}',
             dataType: "json",
             success: function (data) {
                 loadMessageAfterSend(toProfileID, userProfileID);
                 $("#<%=PanelMessageDelete.ClientID%>").hide();
                 $("#message").val("");
                 $("#delMessageContainer").show();
                 $("#msgPanel").show();
             },
             error: function (result) {
                 alert("message sending failed");
             }
         });
     }
     else {
         alert("Please type message in message box.");
         $("#message").focus();

     }
 }

 String.prototype.replaceAll = function (find, replace) {
     var str = this;
     return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
 };



यदि लाइब्रेरी का उपयोग करना आपके लिए एक विकल्प है तो आपको परीक्षण और सामुदायिक सहायता का लाभ मिलेगा जो लाइब्रेरी फ़ंक्शन के साथ आता है। उदाहरण के लिए, string.js लाइब्रेरी में एक प्रतिस्थापित सभी कार्य हैं जो आपके लिए खोज रहे हैं:

// Include a reference to the string.js library and call it (for example) S.
str = S(str).replaceAll('abc', '').s;



function replaceAll(str, find, replace) {
    var $r="";
    while($r!=str){ 
        $r = str;
        str = str.replace(find, replace);
    }
    return str;
}