it-swarm.com.de

Wie zählt man das Auftreten von Strings in Strings?

Wie kann ich zählen, wie oft eine bestimmte Zeichenfolge in einer anderen Zeichenfolge vorkommt? Zum Beispiel versuche ich es in Javascript:

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

Die Variable g im regulären Ausdruck (kurz für global ) besagt, dass die gesamte Zeichenfolge durchsucht werden soll und nicht nur das erste Vorkommen gesucht wird. Dies stimmt zweimal mit is überein:

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

Wenn keine Übereinstimmungen vorhanden sind, wird 0 zurückgegeben:

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

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

Verwendungszweck

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

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

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

allowOverlapping

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

Streichhölzer:

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

Gerätetest

Benchmark

Ich habe einen Benchmark-Test gemacht und meine Funktion ist mehr als 10 Mal Schneller als die von Gumbo gepostete Regex-Match-Funktion. In meinem Test Zeichenfolge ist 25 Zeichen Länge. mit 2 Vorkommen des Zeichens 'o'. ICH 1 000 000 mal in Safari ausgeführt.

Safari 5.1

Benchmark> Ausführungszeit insgesamt: 5617 ms (regexp)

Benchmark> Ausführungszeit gesamt: 881 ms (meine Funktion 6.4x schneller)

Firefox 4

Benchmark> Ausführungszeit gesamt: 8547 ms (Rexexp)

Benchmark> Ausführungszeit gesamt: 634 ms (meine Funktion 13.5x schneller)


Bearbeiten: Änderungen, die ich vorgenommen habe

  • länge der zwischengespeicherten Teilzeichenfolge

  • typ-Casting zu String hinzugefügt.

  • optionaler 'allowOverlapping'-Parameter hinzugefügt

  • korrigierte korrekte Ausgabe für "" leere Teilzeichenfolge.

207
Vitim.us
function countInstances(string, Word) {
   return string.split(Word).length - 1;
}
86
Orbit

Sie können dies versuchen:

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

74
Freezy Ize

Meine Lösung:

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

32
Gere

Sie können match verwenden, um eine solche Funktion zu definieren:

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

Nur Code-Golfing Rebecca Chernoff 's Lösung :-)

alert(("This is a string.".match(/is/g) || []).length);
9
TMS

Die Version ohne 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

9
Faraz Kelhini

Hier ist die schnellste Funktion!

Warum ist es schneller?

  • Prüft nicht char nach char (mit 1 ausnahme)
  • Verwendet eine while-Zeit und inkrementiert 1 var (die Zeichenanzahl var) im Vergleich zu einer for-Schleife, die die Länge überprüft und 2 vars (normalerweise var i und eine var mit der Zeichenanzahl) erhöht.
  • Verwendet WAY weniger Vars
  • Regex nicht verwenden!
  • Verwendet eine (hoffentlich) stark optimierte Funktion
  • Alle Vorgänge sind so kombinierbar, wie es nur möglich ist, und vermeiden Verzögerungen aufgrund mehrerer Vorgänge

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

Hier ist eine langsamere und lesbarere Version:

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

Dieser ist langsamer wegen des Zählers, der langen Variablennamen und des Missbrauchs von 1 Var.

Um es zu benutzen, machst du einfach Folgendes:

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

Edit: (2013/12/16)

NICHT mit Opera 12.16 oder älter verwenden! es wird fast 2,5x mehr als die reguläre Lösung sein!

Auf Chrom dauert diese Lösung für 1.000.000 Zeichen zwischen 14 ms und 20 ms.

Die Regex-Lösung benötigt für die gleiche Menge 11-14 ms.

Die Verwendung einer Funktion (außerhalb von String.prototype) dauert etwa 10-13 ms.

Hier ist der verwendete Code:

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

Das Ergebnis aller Lösungen sollte 100.000 sein!

Hinweis: Wenn Sie möchten, dass diese Funktion mehr als 1 Zeichen zählt, ändern Sie c=(c+'')[0] in c=c+''.

8
Ismael Miguel

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

6
Sunil Garg

Ich denke, der Zweck von regex unterscheidet sich stark von indexOf.indexOf. Sie finden einfach das Vorkommen einer bestimmten Zeichenfolge, während Sie in regex Platzhalterzeichen wie [A-Z] verwenden können. Dies bedeutet, dass jedes Großbuchstabe im Word ohne Angabe von Zeichen gefunden wird der eigentliche Charakter.

Beispiel:

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

4
Simm

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

Dies wird 2 zurückgeben.

4
Fad Seck
       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");

Siehe: - Zählen Sie einen Teilstring in der Zeichenfolge für eine schrittweise Erklärung.

3
Ranju

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

Verwenden Sie get_occurrence (varS, string), um das Auftreten von Zeichen und String in einem String zu finden.

3
Rahul Ranjan

Super duper alt, aber ich musste heute so etwas tun und dachte erst danach, SO zu überprüfen. Funktioniert ziemlich schnell für mich.

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
Jason Larke

Für jeden, der diesen Thread in der Zukunft findet, ist zu beachten, dass die akzeptierte Antwort nicht den korrekten Wert zurückgibt, wenn Sie ihn generalisieren, da er die Regex-Operatoren wie $ und . verschluckt. Hier ist eine bessere Version, die mit any needle umgehen kann:

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

Aufbauend auf @ Vittim.us Antwort oben. Ich mag die Kontrolle, die mir seine Methode bietet, wodurch sie sich leicht erweitern lässt, aber ich musste die Groß- und Kleinschreibung und die Übereinstimmungen mit ganzen Wörtern mit Unterstützung für die Interpunktion begrenzen. ("bad" befindet sich beispielsweise in "baden." aber nicht "baden".)

Der Regex für Interpunktion kam von: https://stackoverflow.com/a/25575009/497745 ( Wie kann ich alle Interpunktionen aus einem String in JavaScript mithilfe von Regex entfernen? )

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

Fühlen Sie sich frei, diese Antwort zu ändern und zu überarbeiten, wenn Sie Fehler oder Verbesserungen feststellen.

3
Ayo I

Versuch es

<?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
The Clouds

Einfache Version ohne Regex:

var temp = "This is a string.";

var count = (temp.split('is').length - 1);

alert(count);

2
Jorge Alberto

Nun, dies ist ein sehr alter Thread, dem ich begegnet bin, aber da viele ihre Antworten gepusht haben, ist hier meiner in der Hoffnung, jemandem mit diesem einfachen Code zu helfen.

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

Ich bin nicht sicher, ob es die schnellste Lösung ist, aber ich habe es der Einfachheit halber vorgezogen, weil ich keinen Regex verwendet habe (ich mag sie einfach nicht!)

1
Tushar Shukla

Antwort für Leandro Batista: Nur ein Problem mit dem Regex-Ausdruck.

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

ist auf diesen Beitrag gestoßen.

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
}

Derselbe Algorithmus kann kürzer ausgelegt werden:

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
Ashok R

Diese Lösung basiert auf der Methode .replace(), die einen RegEx als ersten Parameter und eine Funktion als zweiten Parameter akzeptiert die wir als Abschluss verwenden können, um einen Zähler zu erhöhen ...

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

Verwendungszweck

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

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

Niemand wird das je sehen, aber es ist gut, ab und zu Rekursions- und Pfeilfunktionen wiederzubringen

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

Etwas spät, aber vorausgesetzt, wir haben folgende Zeichenfolge:

var temp = "This is a string.";

Zuerst teilen wir uns auf, was immer Sie suchen, dies gibt ein Array von Strings zurück.

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

Dann erhalten wir die Länge und subtrahieren 1, da die Aufteilung standardmäßig zu einem Array der Größe 1 führt und folglich seine Größe jedes Mal erhöht, wenn ein Vorkommen gefunden wird.

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

Sie können dies alles auch in einer Zeile wie folgt ausführen:

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

Hoffe, es hilft: D

var s = "1";replaced Word
var a = "HRA"; //have to replace 
var str = document.getElementById("test").innerHTML;
var count = str.split(a).length - 1;
for (var i = 0; i < count; i++) {
    var s = "1";
    var a = "HRA";
    var str = document.getElementById("test").innerHTML;
    var res = str.replace(a, s);
    document.getElementById("test").innerHTML = res;
}

<input " type="button" id="Btn_Validate" value="Validate" class="btn btn-info" />
<div class="textarea"  id="test" contenteditable="true">HRABHRA</div>

0
jithin

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
Kamal