วิธีการนับการเกิดสตริงในสตริง?


608

ฉันจะนับจำนวนครั้งที่มีสายอักขระใดเกิดขึ้นในสายอื่นได้อย่างไร ตัวอย่างเช่นนี่คือสิ่งที่ฉันพยายามทำใน Javascript:

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

19
ขึ้นอยู่กับว่าคุณยอมรับอินสแตนซ์ที่ทับซ้อนกันหรือไม่เช่น var t = "sss"; สตริงย่อย "ss" มีกี่อินสแตนซ์ในสตริงด้านบน 1 หรือ 2 คุณก้าวกระโดดข้ามแต่ละอินสแตนซ์หรือย้ายตัวชี้ทีละตัวอักษรเพื่อค้นหาสตริงย่อยหรือไม่?
ทิม

4
มาตรฐานที่ได้รับการปรับปรุงสำหรับคำตอบของคำถามนี้: jsperf.com/string-ocurrence-split-vs-match/2 (อิงตามเกณฑ์มาตรฐานของ Kazzkiq)
idmean

คำตอบ:


1028

gในการแสดงออกปกติ (ย่อมาจากทั่วโลก ) กล่าวว่าในการค้นหาสตริงทั้งมากกว่าแค่การหาสิ่งที่เกิดขึ้นครั้งแรก การแข่งขันisครั้งนี้สองครั้ง:

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


3
ทันสมัยและสง่างาม แต่โซลูชันของ Vitimtk นั้นมีประสิทธิภาพมากกว่า คุณคิดอย่างไรกับรหัสของเขา
TruMan1

5
คำถามนี้ตอบคำถามได้ดีที่สุด หากมีคนถามว่า "ฉันจะทำสิ่งนี้ได้เร็วขึ้น 10 เท่าในกรณีพิเศษ (โดยไม่มี regexps)" Vitimtk จะชนะคำถามนั้น
Dzhaughn

121
ขอบคุณสำหรับสิ่งนี้ .. ฉันไปด้วยcount = (str.match(/is/g) || []).lengthเพื่อจัดการถ้าคุณไม่มีคู่ที่ตรงกัน
แมตต์

6
ฉันไม่คิดว่าคำตอบนี้ตรงกับคำถามอย่างถูกต้องเพราะมันไม่ใช้สตริงเป็นอาร์กิวเมนต์เพื่อให้ตรงกับกรณีใช้อธิบาย แน่นอนว่าคุณสามารถสร้าง regexp แบบไดนามิกโดยใช้คอนRegExpสตรัคเตอร์และส่งผ่านสตริงที่คุณกำลังมองหา แต่ในกรณีนี้คุณจะต้องหลีกเลี่ยงเมทาซีนทั้งหมด ในสถานการณ์สมมตินั้นวิธีการสตริงที่บริสุทธิ์จะดีกว่า
ZER0

3
คำตอบของ Matt ควรเป็นคำตอบ!
Senči

240
/** Function that count occurrences of a substring in a string;
 * @param {String} string               The string
 * @param {String} subString            The sub string to search for
 * @param {Boolean} [allowOverlapping]  Optional. (Default:false)
 *
 * @author Vitim.us https://gist.github.com/victornpb/7736865
 * @see Unit Test https://jsfiddle.net/Victornpb/5axuh96u/
 * @see http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string/7924240#7924240
 */
function occurrences(string, subString, allowOverlapping) {

    string += "";
    subString += "";
    if (subString.length <= 0) return (string.length + 1);

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

    while (true) {
        pos = string.indexOf(subString, pos);
        if (pos >= 0) {
            ++n;
            pos += step;
        } else break;
    }
    return n;
}

การใช้

occurrences("foofoofoo", "bar"); //0

occurrences("foofoofoo", "foo"); //3

occurrences("foofoofoo", "foofoo"); //1

allowOverlapping

occurrences("foofoofoo", "foofoo", true); //2

ตรงกัน:

  foofoofoo
1 `----´
2    `----´

การทดสอบหน่วย

เกณฑ์มาตรฐาน

ฉันได้ทำการทดสอบเกณฑ์มาตรฐานแล้วและฟังก์ชั่นของฉันเร็วขึ้นมากกว่า 10 เท่าจากนั้นฟังก์ชั่นการจับคู่ regexp ที่โพสต์โดยต้นกระเจี๊ยบ ในสตริงทดสอบของฉันมีความยาว 25 ตัวอักษร กับ 2 เหตุการณ์ที่เกิดขึ้นของตัวละคร 'o' ฉันดำเนินการ 1 000 000 ครั้งใน Safari

Safari 5.1

การวัดประสิทธิภาพ> การดำเนินการเวลาทั้งหมด: 5617 ms (regexp)

เกณฑ์มาตรฐาน> การดำเนินการเวลาทั้งหมด: 881 ms (ฟังก์ชั่นของฉันเร็วขึ้น 6.4x)

Firefox 4

มาตรฐาน> เวลาดำเนินการทั้งหมด: 8547 ms (Rexexp)

มาตรฐาน> เวลาดำเนินการทั้งหมด: 634 ms (ฟังก์ชั่นของฉันเร็วขึ้น 13.5x)


แก้ไข: การเปลี่ยนแปลงที่ฉันทำ

  • ความยาวสตริงย่อยที่แคช

  • เพิ่มการหล่อประเภทให้กับสตริง

  • เพิ่มพารามิเตอร์ 'allowOverlapping' ซึ่งเป็นตัวเลือก

  • แก้ไขเอาต์พุตที่ถูกต้องสำหรับกรณีสตริงย่อยว่าง ""

ส่วนสำคัญ

5
ฉันทำซ้ำการทดสอบนี้ใน Safari 5 และได้ผลลัพธ์ที่คล้ายกันกับสตริง (100b) ขนาดเล็ก แต่ด้วยสตริงที่มีขนาดใหญ่กว่า (16kb) regex ทำงานได้เร็วขึ้นสำหรับฉัน สำหรับการวนซ้ำหนึ่งครั้ง (ไม่ใช่ 1,000,000) ความแตกต่างน้อยกว่ามิลลิวินาทีดังนั้นการลงคะแนนของฉันไปที่ regex
arlomedia

2
+1 แต่คุณกำลังตรวจสอบsubstring.lengthเกือบทุกวงคุณควรพิจารณาแคชนอกwhile
ajax333221

1
@ ajax333221 OMG ที่คุณอ่านใจของฉันฉันได้ทำการปรับปรุงนี้ไม่กี่วันที่ผ่านมาและฉันจะแก้ไขคำตอบของฉันjsperf.com/count-string-occurrence-in-string
Vitim.us

4
ผมพบว่ารหัสของคุณในการใช้งานที่นี่: success-equation.com/mind_reader.html ดีจริง ๆ โปรแกรมเมอร์ใจวางการอ้างอิงที่นั่น
บรูโน่คิม

3
@DanielZuzevich มันจะบีบบังคับประเภทให้กับสตริงในกรณีที่คุณทำoccurrences(11,1) //2และมันจะยังคงทำงาน (การทำเช่นนี้ทำได้เร็วกว่าแทนที่จะตรวจสอบประเภทและโทรไปที่
String

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

4
นี่เป็นวิธีที่ไม่ปลอดภัย / ไม่ถูกต้องตัวอย่างเช่น: countInstances("isisisisisis", "is") === 0.
Nick Craver

5
@Antal - ดูเหมือนว่าข้อผิดพลาดในรุ่นเบต้าก่อนหน้าของโครเมี่ยมทำงานหลังจากอัปเดตเป็นรุ่นล่าสุดฉันยังคงหลีกเลี่ยงวิธีการนี้
Nick Craver

28
ดูเหมือนว่าเป็นทางออกที่ถูกต้องสำหรับฉัน
Gregor Schmidt

2
@NickCraver ด้วยความอยากรู้ทำไมคุณต้องการหลีกเลี่ยงวิธีการนี้ (นอกเหนือจากข้อผิดพลาดในเบราว์เซอร์เบต้าของคุณ)
จอนนี่หลิน

6
@ JonnyLin มันสร้างการจัดสรรที่ไม่จำเป็นที่คุณทิ้งทันทีเมื่อมีทางเลือกอื่น - อาจมีขนาดใหญ่มากขึ้นอยู่กับข้อมูล
Nick Craver

88

คุณสามารถลองสิ่งนี้:

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


14
+1 สำหรับความเรียบง่ายและเนื่องจากตามการทดสอบของฉันโซลูชันนี้จะทำงานเร็วกว่าคนอื่น~ 10 เท่า !
Claudio Holanda

ตัวอย่างเช่นฉันมีสอง "คือ" คุณจะได้รับตำแหน่งของแต่ละอย่างไร
quickoodle

ตามที่กล่าวไว้ในคำตอบของ @Orbit ผู้คนจะได้รับผลลัพธ์ที่แตกต่างกันใน Chrome รุ่นเก่า ฉันอาจจะระมัดระวังเล็กน้อยโดยใช้วิธีนี้
mgthomas99

และคุณยังสามารถใช้กับตัวแปร: theString.split(myvar).length - 1ซึ่งคุณไม่สามารถใช้ regex แบบง่ายได้
Steffan

4
นี่เป็นคำตอบของ @Orbit สามปีต่อมา ...
aloisdg ย้ายไป codidact.com

33

ทางออกของฉัน:

var temp = "This is a string.";

function countOcurrences(str, value) {
  var regExp = new RegExp(value, "gi");
  return (str.match(regExp) || []).length;
}

console.log(countOcurrences(temp, 'is'));


5
อาจจะดีกว่าถ้าส่งคืน (str.match (regExp) || []). length; ด้วยวิธีนี้คุณจะไม่ประเมินการแสดงออกปกติสองครั้งใช่ไหม
aikeru

2
คุณจำเป็นต้อง scape สตริงของคุณหรือcountOcurrences('Hello...','.')==8ไม่และ 3
Vitim.us

19

คุณสามารถใช้matchเพื่อกำหนดฟังก์ชั่นดังกล่าว:

String.prototype.count = function(search) {
    var m = this.match(new RegExp(search.toString().replace(/(?=[.\\+*?[^\]$(){}\|])/g, "\\"), "g"));
    return m ? m.length:0;
}

1
ถ้าคุณอยากให้มันเป็นชุดที่มีความหมายของ JS return m ? m.length:-1;ค้นหาสายการกลับมาจะเป็น
Conor O'Brien

นี่จะดีกว่าโซลูชันอื่น ๆ ของ regex ด้านบนเพราะมันจะทำให้เกิดข้อผิดพลาดถ้าสตริงที่จะนับการเกิดของคือ "[" หรืออะไรก็ตามที่มีความหมายพิเศษใน Regex
programmer5000

11

รุ่นที่ไม่ใช่ regex:

 var string = 'This is a string',
    searchFor = 'is',
    count = 0,
    pos = string.indexOf(searchFor);

while (pos > -1) {
    ++count;
    pos = string.indexOf(searchFor, ++pos);
}

console.log(count);   // 2


1. มันเป็นการค้นหาแบบ char เพียงครั้งเดียวที่บอบบางเกินไป 2. แม้ OP จะถามหาสิ่งที่isเกิดขึ้น
vladkras

1
นี่อาจเป็นการใช้งานที่เร็วที่สุดที่นี่ แต่จะเร็วยิ่งขึ้นหากคุณแทนที่ "++ pos" ด้วย "pos + = searchFor.length"
hanshenrik



8

นี่คือฟังก์ชั่นที่เร็วที่สุด!

ทำไมมันเร็วกว่า

  • ไม่ตรวจสอบถ่านด้วยถ่าน (ยกเว้น 1 ข้อ)
  • ใช้ในขณะที่และเพิ่มขึ้น 1 var (char char var) เทียบกับ a สำหรับการตรวจสอบวนรอบความยาวและเพิ่ม 2 vars (ปกติ var i และ var ที่มีจำนวนถ่าน)
  • ใช้ 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 var

ในการใช้งานคุณสามารถทำสิ่งนี้ได้:

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

แก้ไข: (2013/12/16)

อย่าใช้กับ Opera 12.16 ขึ้นไป! จะใช้เวลามากกว่า 2.5x มากกว่าโซลูชัน regex!

สำหรับ Chrome วิธีนี้จะใช้เวลาระหว่าง 14ms ถึง 20ms สำหรับ 1,000,000 ตัวอักษร

วิธีการแก้ปัญหา regex ใช้เวลา 11-14ms สำหรับจำนวนเดียวกัน

การใช้ฟังก์ชั่น (นอก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');

ผลลัพธ์ของการแก้ปัญหาทั้งหมดควรเป็น 100,000!

หมายเหตุ: หากคุณต้องการฟังก์ชั่นนี้จะนับมากกว่า 1 ถ่าน, การเปลี่ยนแปลงที่เป็นc=(c+'')[0]เข้าc=c+''


1
ต้นแบบนั้นเป็นตัวอย่าง! คุณสามารถใช้ฟังก์ชั่นตามที่คุณต้องการ! คุณสามารถทำได้: var timesFunctionExist = function (x, c) {var t = 0, l = 0, c = (c + '') [0]; ในขณะที่ (l = x.indexOf (c, l) +1 ) ++ t; return t}); การแจ้งเตือน (timesCharExist ('ตัวอักษร "a" จะปรากฏขึ้นสองครั้งเท่านั้น', 'a')) ;! (สิ่งนี้จะเพิ่มความเร็วขึ้นอีกเล็กน้อยทำให้ฉันไม่ได้ยุ่งกับต้นแบบ) หากคุณคิดว่าฉันผิดทำไมคุณไม่แสดงก่อนที่จะขว้างก้อนหินใส่ฉัน พิสูจน์กับฉันว่าฟังก์ชั่นของฉันแย่มากและฉันจะยอมรับมัน แสดงกรณีทดสอบให้ฉันดู และความยาวของ vars จะมีผลต่อความเร็ว คุณสามารถทดสอบได้
Ismael Miguel


4

ผมคิดว่าจุดประสงค์ regex indexOfมากแตกต่างจาก indexOfเพียงค้นหาความปรากฎของสตริงบางตัวในขณะที่อยู่ใน regex คุณสามารถใช้ wildcard ได้[A-Z]ซึ่งหมายความว่ามันจะค้นหาตัวพิมพ์ใหญ่ใด ๆในคำโดยไม่ต้องระบุอักขระจริง

ตัวอย่าง:

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


3

Super duper แก่ แต่ฉันต้องทำอะไรเช่นนี้วันนี้และคิดว่าจะตรวจสอบดังนั้นหลังจากนั้น ทำงานได้อย่างรวดเร็วสำหรับฉัน

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

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

อ้างอิง: - นับสตริงย่อยที่ปรากฏในสตริงสำหรับคำอธิบายทีละขั้นตอน


3

สร้างตาม @ Vittim.us ตอบข้างต้น ฉันชอบการควบคุมวิธีการของเขาให้ฉันทำให้ขยายได้ง่าย แต่ฉันต้องการเพิ่มการไม่ตอบสนองต่อตัวพิมพ์เล็กและตัวพิมพ์ใหญ่และ จำกัด ขีด จำกัด ของคำทั้งหมดด้วยการรองรับเครื่องหมายวรรคตอน (เช่น "อาบน้ำ" อยู่ใน "อาบน้ำ" แต่ไม่ใช่ "อาบน้ำ")

regex เครื่องหมายวรรคตอนมาจาก: https://stackoverflow.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\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.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\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }
            }

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

โปรดแก้ไขและทำซ้ำคำตอบนี้หากคุณพบข้อบกพร่องหรือการปรับปรุง


3

สำหรับทุกคนที่พบหัวข้อนี้ในอนาคตทราบว่าคำตอบที่ได้รับการยอมรับจะไม่เคยกลับค่าที่ถูกต้องถ้าคุณคุยมันตั้งแต่มันจะสำลักประกอบ regex ชอบและ$ .ต่อไปนี้เป็นรุ่นที่ดีกว่าที่สามารถจัดการใด ๆเข็ม:

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

3

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) เพื่อค้นหาทั้งอักขระและสตริงใน String


2

ลองมัน

<?php 
$str = "33,33,56,89,56,56";
echo substr_count($str, '56');
?>

<script type="text/javascript">
var temp = "33,33,56,89,56,56";
var count = temp.match(/56/g);  
alert(count.length);
</script>


2

ไม่มีใครเคยเห็นสิ่งนี้ แต่เป็นการดีที่จะนำฟังก์ชั่นการเรียกซ้ำและลูกศรกลับมาอีกครั้งหนึ่ง (ตั้งใจจะใช้งานอย่างมีเกียรติ)

String.prototype.occurrencesOf = function(s, i) {
 return (n => (n === -1) ? 0 : 1 + this.occurrencesOf(s, n + 1))(this.indexOf(s, (i || 0)));
};

2

ลองสิ่งนี้

let allData =  "This is a string.";
let searchString = 'is';
let regularExp = new RegExp(searchString, 'g');
let occurArray = allData.match(regularExp);
let count = (occurArray || []).length;
alert(count); 

Fiddle Link: https://jsfiddle.net/rajaramtt/gn0dtsjc/1/


1

ตอนนี้เป็นเธรดเก่ามากที่ฉันเจอ แต่มีหลายคนที่ผลักคำตอบของพวกเขานี่คือความหวังของฉันที่จะช่วยคนที่มีรหัสง่าย ๆ นี้

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 && "string" === typeof letter ? letter : "";
var count;
for (var i = count = 0; i < search_value.length; count += (search_value[i++] == letter));
console.log(count);

ฉันไม่แน่ใจว่ามันเป็นทางออกที่เร็วที่สุด แต่ฉันชอบมันเพื่อความง่ายและไม่ใช้ regex (ฉันแค่ไม่ชอบใช้มัน!)


1

ฟังก์ชันนี้คืนค่าจำนวนครั้งของคำในข้อความ

หมายเหตุเราใช้ toLowerCase ในการคำนวณจำนวนครั้งที่เกิดอะไรก็ตามรูปแบบ (ตัวพิมพ์ใหญ่, ตัวพิมพ์ใหญ่ ... ) ของคำและข้อความ

wordCount(text, word) {
    if (!text || !word) {
      return 0;
    }
    text = text.toLowerCase();
    word = word.toLowerCase();
    return ( text.split( word ).length - 1 );
}

0

คำตอบสำหรับ Leandro Batista: มีปัญหากับการแสดงออกของ regex

 "use strict";
 var dataFromDB = "testal";
 
  $('input[name="tbInput"]').on("change",function(){
	var charToTest = $(this).val();
	var howManyChars = charToTest.length;
	var nrMatches = 0;
	if(howManyChars !== 0){
		charToTest = charToTest.charAt(0);
		var regexp = new RegExp(charToTest,'gi');
		var arrMatches = dataFromDB.match(regexp);
		nrMatches = arrMatches ? arrMatches.length : 0;
	}
		$('#result').html(nrMatches.toString());

  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
What do you wanna count <input type="text" name="tbInput" value=""><br />
Number of occurences = <span id="result">0</span>
</div>


0

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


0

สายเล็กน้อย แต่สมมติว่าเรามีสตริงต่อไปนี้:

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'

หวังว่ามันจะช่วย: D


1
ฉันสามารถตั้งค่าสถานะนี้เป็นคำตอบที่ซ้ำกันได้หรือไม่ บางทีคุณควรอ่านคำตอบทั้งหมดก่อนแสดงของคุณเอง?
Michiel

2
นี่คือคำตอบของ @Orbit แปดปีต่อมา ...
aloisdg ย้ายไป codidact.com

1
ฉันควรจะลบคำตอบนี้ไหม
Juan Enrique Segebre

0

วิธีการแก้ปัญหานี้จะขึ้นอยู่กับ.replace()วิธีการที่ยอมรับ RegEx เป็นพารามิเตอร์แรกและฟังก์ชั่นเป็นพารามิเตอร์ที่สองที่เราสามารถใช้เป็นปิดเพื่อเพิ่มเคาน์เตอร์ ...

/**
 * Return the frequency of a substring in a string
 * @param {string} string - The string.
 * @param {string} string - The substring to count.
 * @returns {number} number - The frequency.
 * 
 * @author Drozerah https://gist.github.com/Drozerah/2b8e08d28413d66c3e63d7fce80994ce
 * @see https://stackoverflow.com/a/55670859/9370788
 */
const subStringCounter = (string, subString) => {

    let count = 0
    string.replace(new RegExp(subString, 'gi'), () => count++)
    return count
}

การใช้

subStringCounter("foofoofoo", "bar"); //0

subStringCounter("foofoofoo", "foo"); //3

0

เจอโพสต์นี้

let str = 'As sly as a fox, as strong as an ox';

let target = 'as'; // let's look for it

let pos = 0;
while (true) {
  let foundPos = str.indexOf(target, pos);
  if (foundPos == -1) break;

  alert( `Found at ${foundPos}` );
  pos = foundPos + 1; // continue the search from the next position
}

อัลกอริทึมแบบเดียวกันสามารถจัดวางให้สั้นลงได้:

let str = "As sly as a fox, as strong as an ox";
let target = "as";

let pos = -1;
while ((pos = str.indexOf(target, pos + 1)) != -1) {
  alert( pos );
}

0

substr_count แปลเป็น Javascript จาก php


function substr_count (haystack, needle, offset, length) { 
  // eslint-disable-line camelcase
  //  discuss at: https://locutus.io/php/substr_count/
  // original by: Kevin van Zonneveld (https://kvz.io)
  // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Brett Zamir (https://brett-zamir.me)
  // improved by: Thomas
  //   example 1: substr_count('Kevin van Zonneveld', 'e')
  //   returns 1: 3
  //   example 2: substr_count('Kevin van Zonneveld', 'K', 1)
  //   returns 2: 0
  //   example 3: substr_count('Kevin van Zonneveld', 'Z', 0, 10)
  //   returns 3: false

  var cnt = 0

  haystack += ''
  needle += ''
  if (isNaN(offset)) {
    offset = 0
  }
  if (isNaN(length)) {
    length = 0
  }
  if (needle.length === 0) {
    return false
  }
  offset--

  while ((offset = haystack.indexOf(needle, offset + 1)) !== -1) {
    if (length > 0 && (offset + needle.length) > length) {
      return false
    }
    cnt++
  }

  return cnt
}

ตรวจสอบการแปลฟังก์ชั่น substr_count ของ Php Locutus


-2

ลองสิ่งนี้:

function countString(str, search){
    var count=0;
    var index=str.indexOf(search);
    while(index!=-1){
        count++;
        index=str.indexOf(search,index+1);
    }
    return count;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.