regex - كيفية استبدال كل تواجد سلسلة في JavaScript؟




string replace (25)

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

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

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

يمكنك الرجوع المثال التفصيلي here .

لدي هذه السلسلة:

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

فعل

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

يبدو فقط لإزالة التواجد الأول من abc في السلسلة أعلاه. كيف يمكنني استبدال جميع تكرارات ذلك؟


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

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


// قم بتكرارها حتى يأتي رقم التكرار إلى 0. أو ببساطة انسخ / لصق

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

يمكنني استخدام p لتخزين النتيجة من استبدال الاستعادة السابق:

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

ستحل محل جميع التكرارات في السلسلة s حتى يصبح من الممكن:

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

لتجنب حلقة لا نهائية ، أتفقد ما إذا كان r البديل يحتوي على تطابق m :

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

فيما يلي وظيفة النموذج الأولي استنادًا إلى الإجابة المقبولة:

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"

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

'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

لنفترض أنك تريد استبدال كل "abc" بـ "x":

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

كنت أحاول التفكير في شيء أكثر بساطة من تعديل النموذج الأولي.


فقط إضافة /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 تعني عالميًا


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

str.replace(/abc(\s|$)/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, '');

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


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

عملت بشكل أفضل بالنسبة لي من الإجابات المذكورة أعلاه. حيث يقوم new RegExp("abc", 'g') بإنشاء RegExp الذي يطابق كل التواجدات ( 'g' flag) للنص ( "abc" ). الجزء الثاني هو ما يتم استبداله ، في حالتك سلسلة فارغة ( "" ). str هي السلسلة ، ويجب علينا تجاوزها ، حيث أن replace(...) يرجع فقط النتيجة ، ولكن لا يتم تجاوزها. في بعض الحالات ، قد ترغب في استخدام ذلك.


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

ملاحظة: تحتوي التعبيرات العادية على أحرف خاصة (meta) ، وعلى هذا النحو من الخطر أن يتم تمرير حجة عمياء في وظيفة find أعلاه دون معالجة مسبقة للهروب من تلك الأحرف. يتم تغطيتها في دليل جافا سكريبت الخاص بشبكة مطوري برامج Mozilla على التعبيرات العادية ، حيث تعرض وظيفة الأداة المساعدة التالية:

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

ومن أجل جعل وظيفة replaceAll() أعلاه أكثر أمانًا ، يمكن تعديلها لما يلي إذا قمت أيضًا بتضمين escapeRegExp :

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

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

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

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

هذا هو أسرع إصدار لا يستخدم تعبيرات عادية .

jsperf المنقحة

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

يكاد يكون أسرع مرتين من طريقة الانقسام والانضمام.

كما هو replaceAll("string", "s", "ss") في تعليق هنا ، لن يعمل هذا إذا احتوى متغير replaceAll("string", "s", "ss") على place ، كما في: replaceAll("string", "s", "ss") ، لأنه سيكون قادرًا على استبدال تكرار آخر للكلمة .

هناك jsperf آخر مع المتغيرات على بلدي استبدال متكررة أن تذهب أسرع ( http://jsperf.com/replace-all-vs-split-join/12 )!

  • التحديث بتاريخ 27 يوليو 2017: يبدو أن RegExp أصبح الآن أسرع أداء في إصدار Chrome 59 الذي تم إصداره مؤخرًا.

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

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

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

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

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

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

آمل أن يساعد!


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

http://jsfiddle.net/ANHR9/


إذا كان ما تريد أن تجده موجودًا بالفعل في سلسلة ، ولم يكن لديك أمر تعديل في متناول اليد ، يمكنك استخدام الانضمام / الانقسام:

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

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


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

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

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

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

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

انظر هنا أيضا


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

أو جرب وظيفة replaceAll من هنا:

ما هي طرق جافا سكريبت المفيدة التي تمدّ الأشياء المدمجة؟

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

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

تحرير: توضيح حول replaceAll توافر

تتم إضافة طريقة "replaceAll" إلى النموذج الأولي للمجموعة. هذا يعني أنه سيكون متاحًا لجميع كائنات السلسلة / القيم الحرفية.

على سبيل المثال

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

function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

تقوم بعض الإجابات الأخرى بتعديل String.prototype (هذه الإجابة المستخدمة أيضًا) ، ولكني أنصح بعدم وجود هذا الآن بسبب إمكانية الصيانة (من الصعب معرفة مكان إضافة الوظيفة إلى prototype وقد تتسبب في حدوث تعارضات إذا كانت الشفرة الأخرى تستخدم نفس الشيء) اسم / متصفح يضيف وظيفة أصلية بنفس الاسم في المستقبل).





javascript regex string replace