javascript - معنى - ماهو الجزء المفقود من هذه الدالة؟ function add{var c=a+b; return c;}




كيفية استبدال كل تواجد سلسلة في JavaScript؟ (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;
    }

أنا أحب هذه الطريقة (يبدو قليلا نظافة):

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

إذا كانت السلسلة تحتوي على نمط مماثل مثل abccc ، فيمكنك استخدام هذا:

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

إذا كنت تحاول التأكد من أن السلسلة التي تبحث عنها لن تظهر حتى بعد الاستبدال ، فستحتاج إلى استخدام حلقة.

فمثلا:

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

عند الاكتمال ، سيظل لديك "abc test"!

سيكون أبسط حلقة لحل هذا:

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" ونريد إزالة جميع الفواصل المكررة.
[في هذه الحالة ، يمكن للمرء أن يفعل. استبدال (/ ، + / g ، '،') ، ولكن في مرحلة ما ، يصبح تعبير regex معقدًا وبطيء بما فيه الكفاية لحلقة بدلًا من ذلك.]


استخدم تعبير عادي:

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

باستخدام RegExp في JavaScript يمكن أن يقوم بالمهمة نيابة عنك ، فقط قم ببساطة بعمل شيء من هذا القبيل:

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

ولكن كما ذكرت سابقًا ، لن يحدث اختلاف كبير من حيث الخطوط المكتوبة أو الأداء ، إلا أن التخزين المؤقت للوظيفة قد يؤثر فقط على أداء أسرع على سلاسل طويلة ، وكذلك ممارسة جيدة من كود جاف إذا كنت تريد إعادة استخدامها.


تعمل وظيفة التالية بالنسبة لي:

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

ما عليك سوى نسخ هذا الرمز ولصقه في وحدة تحكم المتصفح لإجراء الاختبار.


سيؤدي استخدام التعبير العادي مع مجموعة علم g إلى استبدال الكل:

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

انظر هنا أيضا


فقط إضافة /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.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/


ما عليك سوى اتباع هذا التعبير المعيّن لإضافة الحساسية لحالة الأحرف ، لذلك إذا فعلت "ABC" ، فسيعمل ذلك بنفس طريقة "abc".

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

من أجل الاكتمال ، توصلت إلى التفكير في الطريقة التي يجب أن أستخدمها للقيام بذلك. هناك طريقتان أساسيتان للقيام بذلك كما هو مقترح من الإجابات الأخرى في هذه الصفحة.

ملاحظة: بشكل عام ، لا يُوصى عمومًا بتوسيع النماذج الأولية المضمنة في جافا سكريبت. أنا أقدم كتمديدات على النموذج الأولي للسلسلة ببساطة لأغراض التوضيح ، حيث تظهر تطبيقات مختلفة لطريقة قياسية افتراضية على النموذج الأولي المدمج في 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);
};

لا أعرف الكثير عن كيفية عمل التعبيرات العادية خلف الكواليس من حيث الكفاءة ، فقد مالت إلى الانقسام نحو الانضمام والانضمام إلى التطبيق في الماضي دون التفكير في الأداء. عندما كنت أتساءل أيهما كان أكثر كفاءة ، وبأي هامش ، استخدمته كعذر لمعرفة ذلك.

على جهاز Chrome Windows 8 ، يكون التنفيذ المستند إلى التعبير العادي هو الأسرع ، حيث يكون تنفيذ الانقسام والمشاركة أبطأ بنسبة 53٪ . بمعنى أن التعبيرات المعتادة تكون أسرع مرتين من إدخال ipsum lorem lang.

تحقق من هذا benchmark تشغيل هذين التطبيقين ضد بعضها البعض.

كما هو مذكور في التعليق أدناه بواسطةThomasLeduc وغيره ، قد تكون هناك مشكلة في التنفيذ المعتمد على التعبير العادي إذا كان search يحتوي على أحرف معينة محجوزة كأحرف خاصة في التعبيرات العادية . يفترض التنفيذ أن المتصل سيخرج من السلسلة مسبقًا أو سيؤدي فقط إلى تمرير سلاسل غير موجودة في الجدول في التعبيرات العادية (MDN).

يوفر MDN أيضا تنفيذ للهروب من خيوطنا. سيكون من الجيد إذا تم توحيد ذلك أيضًا كـ RegExp.escape(str) ، لكن للأسف ، فإنه غير موجود:

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

يمكننا استدعاء escapeRegExp داخل تطبيق String.prototype.replaceAll ، ومع ذلك ، لست متأكدًا من مدى تأثير ذلك على الأداء (ربما حتى بالنسبة للسلاسل التي لا تحتاج إلى الهروب ، مثل جميع السلاسل الأبجدية الرقمية).


يمكنك ببساطة استخدام الطريقة أدناه

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

يمكنك محاولة الجمع بين هذين الأسلوبين الأقوياء.

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

آمل أن يساعد!


تحديث:

إنه متأخر بعض الشيء عن التحديث ، ولكن بما أنني تعثرت في هذا السؤال ، ولاحظت أن إجابتي السابقة ليست واحدة أنا سعيد بها. نظرًا لأن السؤال يتعلق باستبدال كلمة واحدة ، فمن غير المعقول التفكير في استخدام حدود الكلمات ( \b )

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

هذا تعبير عادي يتجنب استبدال أجزاء الكلمات في معظم الحالات. ومع ذلك ، لا تزال تعتبر شرطة - حدود كلمة. لذلك ، يمكن استخدام الشروط الشرطية في هذه الحالة لتجنب استبدال السلاسل مثل:

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

في الأساس ، يكون هذا السؤال هو نفس السؤال هنا: استبدال جافا سكريبت "" "بـ" "" "

Mike ، والتحقق من الإجابة التي قدمتها هناك ... regexp ليس هو السبيل الوحيد لاستبدال تكرارات متعددة من الغسل ، بعيدا عن ذلك. اعتقد مرنة ، والتفكير الانقسام!

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" ?? 

عفوًا ، ربما هذا ليس ما تريده. ما هو ثم؟ IMHO ، تعبير عادي يستبدل فقط "قطة" مشروطًا. (أي ليس جزءًا من كلمة) ، مثل:

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

الإضافة النهائية:

وبالنظر إلى أن هذا السؤال لا يزال يحصل على الكثير من المشاهدات ، فقد ظننت أنني قد أضيف مثالًا على .replace المستخدم مع وظيفة رد اتصال. في هذه الحالة ، يبسط التعبير بشكل كبير ويوفر مرونة أكثر ، مثل استبدال الأحرف الكبيرة أو استبدال 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

ملاحظة: لا تستخدم هذا في الكود الحقيقي.

كبديل للتعبيرات العادية لسلسلة حرفية بسيطة ، يمكنك استخدامها

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' flag) للنص ( "abc" ). الجزء الثاني هو ما يتم استبداله ، في حالتك سلسلة فارغة ( "" ). str هي السلسلة ، ويجب علينا تجاوزها ، حيث أن replace(...) يرجع فقط النتيجة ، ولكن لا يتم تجاوزها. في بعض الحالات ، قد ترغب في استخدام ذلك.


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




replace