javascript شرح كيفية حساب حدوث سلسلة في السلسلة؟




regular expression شرح (17)

أعتقد أن الغرض من regex يختلف كثيرًا عن indexOf . indexOf ببساطة العثور على حدوث سلسلة معينة أثناء تعبير regex يمكنك استخدام أحرف البدل مثل [AZ] مما يعني أنه سيعثر على أي حرف رأس في الكلمة بدون ذكر الحرف الفعلي.

مثال:

 var index = "This is a string".indexOf("is");
 console.log(index);
 var length = "This is a string".match(/[a-z]/g).length;
 // where [a-z] is a regex wildcard expression thats why its slower
 console.log(length);

https://code.i-harness.com

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

var temp = "This is a string.";
alert(temp.count("is")); //should output '2'

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

var search_value = "This is a dummy sentence!";
var letter = 'a'; /*Can take any letter, have put in a var if anyone wants to use this variable dynamically*/
letter = letter[letter.length - 1];
var count;
for (var i = count = 0; i < search_value.length; count += (search_value[i++] == letter));
console.log(count);

لست متأكدا ما إذا كان هذا هو الحل الأسرع ولكني فضلت ذلك للبساطة وعدم استخدام regex (أنا لا أحب استخدامها!)


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

String.prototype.count = function(substr,start,overlap) {
    overlap = overlap || false;
    start = start || 0;

    var count = 0, 
        offset = overlap ? 1 : substr.length;

    while((start = this.indexOf(substr, start) + offset) !== (offset - 1))
        ++count;
    return count;
};

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

function occurrences (haystack, needle) {
  var _needle = needle
    .replace(/\[/g, '\\[')
    .replace(/\]/g, '\\]')
  return (
    haystack.match(new RegExp('[' + _needle + ']', 'g')) || []
  ).length
}

بناء على @ Vittim.us الإجابة أعلاه. أنا أحب التحكم الذي يمنحه لي أسلوبه ، مما يجعله سهلًا للتوسع ، ولكني في حاجة إلى إضافة عدم مراعاة الحالة والحد من التطابق مع الكلمات بأكملها مع دعم علامات الترقيم. (على سبيل المثال "حمام" في "أخذ حمام." ولكن ليس "الاستحمام")

تم وضع regex الترقيم من: https://.com/a/25575009/497745 ( كيف يمكنني تجريد كل علامات الترقيم من سلسلة في JavaScript باستخدام regex؟ )

function keywordOccurrences(string, subString, allowOverlapping, caseInsensitive, wholeWord)
{

    string += "";
    subString += "";
    if (subString.length <= 0) return (string.length + 1); //deal with empty strings

    if(caseInsensitive)
    {            
        string = string.toLowerCase();
        subString = subString.toLowerCase();
    }

    var n = 0,
        pos = 0,
        step = allowOverlapping ? 1 : subString.length,
        stringLength = string.length,
        subStringLength = subString.length;

    while (true)
    {
        pos = string.indexOf(subString, pos);
        if (pos >= 0)
        {
            var matchPos = pos;
            pos += step; //slide forward the position pointer no matter what

            if(wholeWord) //only whole word matches are desired
            {
                if(matchPos > 0) //if the string is not at the very beginning we need to check if the previous character is whitespace
                {                        
                    if(!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]/.test(string[matchPos - 1])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }

                var matchEnd = matchPos + subStringLength;
                if(matchEnd < stringLength - 1)
                {                        
                    if (!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }
            }

            ++n;                
        } else break;
    }
    return n;
}

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


جرب هذا:

function countString(str, search){
    var count=0;
    var index=str.indexOf(search);
    while(index!=-1){
        count++;
        index=str.indexOf(search,index+1);
    }
    return count;
}

فقط لعبة غولف رمز الحل أعلاه :-)

alert("This is a string." + match(/is/g).length);


متأخر قليلا ولكن على افتراض أننا لدينا السلسلة التالية:

var temp = "This is a string.";

أولا نقسم على كل ما كنت تتطلع لمطابقة ، وهذا سيعود مجموعة من السلاسل.

var array = temp.split("is");

ثم نحصل على طوله ونطرح 1 إليه منذ تقسيم الافتراضات إلى صفيف من الحجم 1 ونتيجة لذلك يزيد حجمه في كل مرة يجد فيه تكرارا.

var occurrenceCount = array.length - 1;
alert(occurrenceCount); //should output '2'

يمكنك أيضًا القيام بكل ذلك في سطر واحد كما يلي:

alert("This is a string.".split("is").length - 1); //should output '2'

آمل أن يساعد: د


هنا هي أسرع وظيفة!

لماذا هو أسرع؟

  • لا يتم التحقق من char بواسطة char (باستثناء واحد)
  • يستخدم بعض الوقت ويزيد 1 var (char count var) مقابل حلقة مفرغة لفحص الطول وزياده 2 vars (عادة var i و var مع عدد char)
  • يستخدم طريقة أقل vars
  • لا تستخدم regex!
  • يستخدم وظيفة (نأمل) للغاية الأمثل
  • يتم الجمع بين جميع العمليات كما يمكن ، وتجنب التباطؤ بسبب عمليات متعددة

    String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
    

هنا هو إصدار أبطأ وأكثر قابلية للقراءة:

    String.prototype.timesCharExist = function ( chr ) {
        var total = 0, last_location = 0, single_char = ( chr + '' )[0];
        while( last_location = this.indexOf( single_char, last_location ) + 1 )
        {
            total = total + 1;
        }
        return total;
    };

هذا واحد أبطأ بسبب العداد ، وأسماء var طويلة وإساءة استخدام 1 فار.

لاستخدامها ، يمكنك القيام بذلك ببساطة:

    'The char "a" only shows up twice'.timesCharExist('a');

تحرير: (2013/12/16)

لا تستخدم مع أوبرا 12.16 أو أكثر! سوف يستغرق الأمر أكثر من 2.5x أكثر من حل regex!

على الكروم ، سيستغرق هذا الحل ما بين 14 و 20 مللي ثانية لكل 1000،000 حرف.

يستغرق حل regex 11-14 مللي ثانية بنفس المقدار.

استخدام وظيفة (خارج String.prototype ) سوف يستغرق حوالي 10-13ms.

هنا الشفرة المستخدمة:

    String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};

    var x=Array(100001).join('1234567890');

    console.time('proto');x.timesCharExist('1');console.timeEnd('proto');

    console.time('regex');x.match(/1/g).length;console.timeEnd('regex');

    var timesCharExist=function(x,c){var t=0,l=0,c=(c+'')[0];while(l=x.indexOf(c,l)+1)++t;return t;};

    console.time('func');timesCharExist(x,'1');console.timeEnd('func');

يجب أن تكون نتيجة كل الحلول 100000!

ملاحظة: إذا كنت تريد أن تقوم هذه الدالة بحساب أكثر من 1 حرف ، قم بتغيير مكان c=(c+'')[0] إلى c=c+''


يقول g في التعبير العادي (اختصار عالمي ) للبحث في السلسلة بأكملها بدلاً من مجرد العثور على التواجد الأول:

var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);

هذه المباريات مرتين. وإذا لم تكن هناك تطابقات ، فإنها ترجع 0 .

var temp = "Hello World!";
var count = (temp.match(/is/g) || []).length;
console.log(count);


يمكنك تجربة هذا:

var theString = "This is a string.";
console.log(theString.split("is").length - 1);


String.prototype.Count = function (find) { return this.split(find).length - 1; } "This is a string.".Count("is");

هذا سيعود 2.


function get_occurrence(varS,string){//Find All Occurrences
        c=(string.split(varS).length - 1);
        return c;
    }
    temp="This is a string.";
    console.log("Total Occurrence is "+get_occurrence("is",temp));

استخدم get_occurrence (varS ، string) للبحث عن تواجد كل من الحروف والسلسلة في سلسلة.


var countInstances = function(body, target) {
  var globalcounter = 0;
  var concatstring  = '';
  for(var i=0,j=target.length;i<body.length;i++){
    concatstring = body.substring(i-1,j);
    
    if(concatstring === target){
       globalcounter += 1;
       concatstring = '';
    }
  }
  
  
  return globalcounter;
 
};

console.log(   countInstances('abcabc', 'abc')   ); // ==> 2
console.log(   countInstances('ababa', 'aba')   ); // ==> 2
console.log(   countInstances('aaabbb', 'ab')   ); // ==> 1


var temp = "This is a string.";
console.log((temp.match(new RegExp("is", "g")) || []).length);


       var myString = "This is a string.";
        var foundAtPosition = 0;
        var Count = 0;
        while (foundAtPosition != -1)
        {
            foundAtPosition = myString.indexOf("is",foundAtPosition);
            if (foundAtPosition != -1)
            {
                Count++;
                foundAtPosition++;
            }
        }
        document.write("There are " + Count + " occurrences of the word IS");

راجع: - تظهر سلسلة فرعية في السلسلة للتوضيح خطوة بخطوة.


function countInstances(string, word) {
   return string.split(word).length - 1;
}






string