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




regex string (20)

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

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

करते हुए

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

ऐसा लगता है कि उपर्युक्त स्ट्रिंग में केवल abc की पहली घटना को हटा दें। मैं इसकी सभी घटनाओं को कैसे बदल सकता हूं?


// इसे तब तक लूप करें जब तक कि संख्या घटनाएं 0 तक नहीं आतीं या बस प्रतिलिपि / पेस्ट करें

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

आप इन दो शक्तिशाली तरीकों को संयोजित करने का प्रयास कर सकते हैं।

"test abc test test abc".split("abc").join("")

आशा करता हूँ की ये काम करेगा!


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

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

केस-सेंसिटीविटी को जोड़कर इस ऑनलाइनर रेगेक्स का पालन करें, इसलिए यदि आप "एबीसी" करते हैं, तो यह "एबीसी" के समान ही कार्य करेगा।

str = str.replace(/abc/gi, "");

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

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

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

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

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

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% धीमी है । मेरे द्वारा उपयोग किए जाने वाले लोरेम इप्सम इनपुट के लिए नियमित अभिव्यक्ति दो गुना तेज होती है।

एक दूसरे के खिलाफ इन दो कार्यान्वयन को चलाने वाले इस benchmark देखें।

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

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

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

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


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

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

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


मुझे यह विधि पसंद है (यह थोड़ा क्लीनर दिखता है):

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

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

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

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));


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

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

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 '!

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


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

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

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

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


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

संशोधित जेएसपीआरएफ

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 में RegExp का सबसे तेज़ प्रदर्शन है।

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

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/


g फ्लैग सेट के साथ नियमित अभिव्यक्ति का उपयोग करना सभी को प्रतिस्थापित करेगा:

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

यहां भी देखें


जावास्क्रिप्ट में RegExp का उपयोग करना आपके लिए काम कर सकता है, बस बस कुछ ऐसा करें:

var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);

यदि आप पुन: उपयोग करने के बारे में सोचते हैं, तो आपके लिए ऐसा करने के लिए एक फ़ंक्शन बनाएं, लेकिन इसकी अनुशंसा नहीं की जाती है क्योंकि यह केवल एक पंक्ति कार्य है, लेकिन फिर यदि आप इसका उपयोग करते हैं, तो आप इस तरह कुछ लिख सकते हैं:

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

और बस इसे अपने कोड में नीचे और नीचे की तरह उपयोग करें:

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

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


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

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

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

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

str.split(search).join(replacement)

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


String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
  return this.replace(new RegExp(string, 'g'), replaced);
};

http://jsfiddle.net/ANHR9/


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

str = str.replace(new RegExp("abc", 'g'), "");

उपरोक्त उत्तरों की तुलना में मेरे लिए बेहतर काम किया। तो new RegExp("abc", 'g') एक RegExp बनाता है जो पाठ के सभी अवसर ( 'g' ध्वज) से मेल खाता है ( "abc" )। दूसरे भाग को आपके मामले में खाली स्ट्रिंग ( "" ) में बदल दिया जाता है। str स्ट्रिंग है, और हमें इसे ओवरराइड करना है, क्योंकि replace(...) केवल परिणाम देता है, लेकिन ओवरराइड नहीं करता है। कुछ मामलों में आप इसका उपयोग करना चाहेंगे।


var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');







replace