¿Cómo puedo contar la cantidad de veces que una cadena en particular ocurre en otra cadena? Por ejemplo, esto es lo que estoy tratando de hacer en Javascript:
var temp = "This is a string.";
alert(temp.count("is")); //should output '2'
¿Cómo puedo contar la cantidad de veces que una cadena en particular ocurre en otra cadena? Por ejemplo, esto es lo que estoy tratando de hacer en Javascript:
var temp = "This is a string.";
alert(temp.count("is")); //should output '2'
Respuestas:
La g
expresión regular (abreviatura de global ) dice buscar en toda la cadena en lugar de solo encontrar la primera aparición. Esto coincide is
dos veces:
var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Y, si no hay coincidencias, devuelve 0
:
var temp = "Hello World!";
var count = (temp.match(/is/g) || []).length;
console.log(count);
count = (str.match(/is/g) || []).length
a manejar si no tienes una coincidencia.
RegExp
constructor y pasando la cadena que está buscando, pero en ese caso debe escapar de todos los metacaracteres. En ese escenario, es preferible un enfoque de cadena pura.
/** 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
occurrences("foofoofoo", "foofoo", true); //2
Partidos:
foofoofoo
1 `----´
2 `----´
EsenciaHice una prueba de referencia y mi función es más de 10 veces más rápida que la función de coincidencia regexp publicada por gumbo. En mi cadena de prueba es de 25 caracteres de longitud. con 2 ocurrencias del caracter 'o'. Ejecuté 1 000 000 de veces en Safari.
Safari 5.1
Benchmark> Tiempo total de ejecución: 5617 ms (regexp)
Benchmark> Ejecución de tiempo total: 881 ms (mi función 6.4x más rápido)
Firefox 4
Benchmark> Tiempo total de ejecución: 8547 ms (Rexexp)
Benchmark> Ejecución de tiempo total: 634 ms (mi función 13.5x más rápido)
Editar: cambios que he realizado
longitud de la subcadena en caché
Se agregó la conversión de tipos a la cadena.
Se agregó el parámetro opcional 'allowOverlapping'
se corrigió la salida correcta para el caso de "" subcadena vacía.
substring.length
en casi todos los bucles, debería considerar while
occurrences(11,1) //2
y aún funcionaría. (Es más rápido hacerlo de esta manera en lugar de buscar tipos y llamar a String () )
function countInstances(string, word) {
return string.split(word).length - 1;
}
countInstances("isisisisisis", "is") === 0
.
Puedes probar esto:
var theString = "This is a string.";
console.log(theString.split("is").length - 1);
theString.split(myvar).length - 1
que no puede usar con expresiones regulares simples
Mi solución:
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'));
countOcurrences('Hello...','.')==8
no 3
Puede usar match
para definir dicha función:
String.prototype.count = function(search) {
var m = this.match(new RegExp(search.toString().replace(/(?=[.\\+*?[^\]$(){}\|])/g, "\\"), "g"));
return m ? m.length:0;
}
return m ? m.length:-1;
.
La versión no 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
is
ocurrencias
Simplemente codifique el golf de la solución de Rebecca Chernoff :-)
alert(("This is a string.".match(/is/g) || []).length);
String.prototype.Count = function (find) {
return this.split(find).length - 1;
}
console.log("This is a string.".Count("is"));
Esto devolverá 2.
¡Aquí está la función más rápida!
¿Por qué es más rápido?
Todas las operaciones son tan combinadas como pueden ser, evitando ralentizaciones debido a múltiples operaciones
String.prototype.timesCharExist=function(c){var t=0,l=0,c=(c+'')[0];while(l=this.indexOf(c,l)+1)++t;return t};
Aquí hay una versión más lenta y más legible:
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;
};
Este es más lento debido al contador, los nombres largos de var y el mal uso de 1 var.
Para usarlo, simplemente haz esto:
'The char "a" only shows up twice'.timesCharExist('a');
Editar: (16/12/2013)
¡NO lo use con Opera 12.16 o anterior! ¡tomará casi 2.5 veces más que la solución regex!
En Chrome, esta solución tomará entre 14ms y 20ms para 1,000,000 de caracteres.
La solución de expresiones regulares tarda 11-14 ms por la misma cantidad.
Usar una función (afuera String.prototype
) tomará aproximadamente 10-13 ms.
Aquí está el código utilizado:
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');
¡El resultado de todas las soluciones debería ser 100,000!
Nota: si desea que esta función cuente más de 1 carácter, cambie dónde está c=(c+'')[0]
enc=c+''
var temp = "This is a string.";
console.log((temp.match(new RegExp("is", "g")) || []).length);
Creo que el propósito de la expresión regular es muy diferente indexOf
.
indexOf
simplemente encuentre la aparición de una determinada cadena mientras que en la expresión regular puede usar comodines, lo [A-Z]
que significa que encontrará cualquier carácter en mayúscula en la palabra sin indicar el carácter real.
Ejemplo:
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);
Súper viejo, pero necesitaba hacer algo como esto hoy y solo pensé en verificar SO después. Funciona bastante rápido para mí.
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;
};
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");
Consulte: - cuente una subcadena aparece en la cadena para obtener una explicación paso a paso.
Sobre la base de @ Vittim.us respuesta anterior. Me gusta el control que me da su método, lo que facilita su extensión, pero necesitaba agregar mayúsculas y minúsculas y limitar las coincidencias a palabras completas con soporte para la puntuación. (por ejemplo, "bañarse" está en "bañarse" pero no en "bañarse")
La expresión regular de puntuación provino de: https://stackoverflow.com/a/25575009/497745 ( ¿Cómo puedo eliminar toda la puntuación de una cadena en JavaScript usando expresiones regulares? )
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;
}
Siéntase libre de modificar y refactorizar esta respuesta si detecta errores o mejoras.
Para cualquiera que encuentre este hilo en el futuro, tenga en cuenta que la respuesta aceptada no siempre devolverá el valor correcto si lo generaliza, ya que se ahogará con operadores de expresiones regulares como $
y .
. Aquí hay una versión mejor, que puede manejar cualquier aguja:
function occurrences (haystack, needle) {
var _needle = needle
.replace(/\[/g, '\\[')
.replace(/\]/g, '\\]')
return (
haystack.match(new RegExp('[' + _needle + ']', 'g')) || []
).length
}
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));
Use get_occurrence (varS, string) para encontrar la ocurrencia de caracteres y cadenas en una cadena.
Intentalo
<?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>
Versión simple sin expresiones regulares:
var temp = "This is a string.";
var count = (temp.split('is').length - 1);
alert(count);
Nadie verá esto, pero es bueno recuperar las funciones de recursión y flecha de vez en cuando (juego de palabras gloriosamente intencionado)
String.prototype.occurrencesOf = function(s, i) {
return (n => (n === -1) ? 0 : 1 + this.occurrencesOf(s, n + 1))(this.indexOf(s, (i || 0)));
};
Prueba esto
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);
Enlace de violín: https://jsfiddle.net/rajaramtt/gn0dtsjc/1/
Ahora, este es un hilo muy antiguo que he encontrado, pero como muchos han enviado sus respuestas, aquí está el mío con la esperanza de ayudar a alguien con este código simple.
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);
No estoy seguro de si es la solución más rápida, pero la prefiero por simplicidad y por no usar expresiones regulares (¡simplemente no me gusta usarlas!)
Esta función devuelve el número de apariciones de una palabra en el texto.
Tenga en cuenta que usamos toLowerCase para calcular el número de apariciones, independientemente del formato (mayúscula, mayúscula ...) de la palabra y el texto
wordCount(text, word) {
if (!text || !word) {
return 0;
}
text = text.toLowerCase();
word = word.toLowerCase();
return ( text.split( word ).length - 1 );
}
Respuesta para Leandro Batista: solo un problema con la expresión 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>
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
Un poco tarde pero, suponiendo que tengamos la siguiente cadena:
var temp = "This is a string.";
Primero nos dividimos en lo que sea que esté buscando para que coincida, esto devolverá una serie de cadenas.
var array = temp.split("is");
Luego obtenemos su longitud y le restamos 1, ya que los valores predeterminados divididos en una matriz de tamaño 1 y, en consecuencia, aumenta su tamaño cada vez que encuentra una ocurrencia.
var occurrenceCount = array.length - 1;
alert(occurrenceCount); //should output '2'
También puede hacer todo esto en una línea de la siguiente manera:
alert("This is a string.".split("is").length - 1); //should output '2'
Espero que ayude: D
Esta solución se basa en el .replace()
método que acepta un RegEx como primer parámetro y una función como segundo parámetro que podemos usar como cierre para incrementar un contador ...
/**
* 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
}
Uso
subStringCounter("foofoofoo", "bar"); //0
subStringCounter("foofoofoo", "foo"); //3
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
}
El mismo algoritmo puede presentarse más corto:
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 );
}
substr_count
traducido a Javascript desde 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
}
Echa un vistazo a la función substr_count de Locutus Translation of Php
Prueba esto:
function countString(str, search){
var count=0;
var index=str.indexOf(search);
while(index!=-1){
count++;
index=str.indexOf(search,index+1);
}
return count;
}