如何计数字符串中的字符串出现?

如何计算特定字符串在另一个字符串中出现的次数。例如,这是我在Javascript中尝试做的:

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

正则表达式中的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);

function countInstances(string, word) {return string.split(word).length - 1;}console.log(countInstances("This is a string", "is"))

您可以使用match定义这样的函数:

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

只是代码高尔夫球丽贝卡·切尔诺夫解决方案:-)

alert(("This is a string.".match(/is/g) || []).length);
/** 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 https://stackoverflow.com/a/7924240/938822*/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

匹配:

  foofoofoo1 `----´2    `----´

单元测试

基准

我做了一个基准测试,我的功能超过10倍比gumbo发布的regexp匹配函数更快。在我的测试中字符串长度为25个字符。有2个字符“o”出现。我在Safari中执行了1 000 000次。

Safari5.1

基准>总执行时间:5617 ms(regexp)

基准>总执行时间:881 ms(我的功能快6.4倍)

火狐4

基准>总执行时间:8547 ms(Rexexp)

基准>总执行时间:634 ms(我的函数快13.5倍)


编辑:我所做的更改

  • 缓存的子字符串长度

  • 将类型转换添加到字符串。

  • 添加了可选的“允许重叠”参数

  • 修复了“”空子字符串大小写的正确输出。

要点

试试这个:

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

你可以试试这个:

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

我认为正则表达式的目的与indexOf大不相同。indexOf简单地找到某个字符串的出现,而在正则表达式中,您可以使用像[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 slowerconsole.log(length);

超级骗人的老,但我今天需要做这样的事情,只是想在事后检查一下。对我来说工作得很快。

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

这是最快的功能!

为什么它更快?

  • 不逐个检查char(有1个例外)
  • 使用一个同时并递增1个var(字符计数var)vs. a for循环检查长度并递增2个var(通常是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};

Here is a slower and more readable 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;};

这个比较慢,因为计数器,长var名称和误用1 var。

要使用它,你只需这样做:

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

编辑:(2013/12/16)

不要使用Opera 12.16或更早版本!它将比regex解决方案多2.5倍!

在chrome上,这个解决方案将需要14毫秒到20毫秒的时间来处理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');

所有解的结果应该是10万!

注意:如果您希望此函数计数超过1个字符,请将c=(c+'')[0]的位置更改为c=c+''

试试看

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

非正则表达式版本:

 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

       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 occurrences (haystack, needle) {var _needle = needle.replace(/\[/g, '\\[').replace(/\]/g, '\\]')return (haystack.match(new RegExp('[' + _needle + ']', 'g')) || []).length}

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

基于上面@Vittim.us答案。我喜欢他的方法给我的控制,使其易于扩展,但我需要添加不区分大小写并限制匹配到支持标点符号的整个单词。(例如,“洗澡”在“洗澡”中,但不是“洗澡”)

标点正则表达式来自:https://stackoverflow.com/a/25575009/497745如何使用regex从JavaScript中的字符串中删除所有标点符号?

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

如果您发现错误或改进,请随时修改和重构此答案。

现在这是我遇到的一个非常古老的线程,但由于许多人都推了他们的答案,这是我的,希望能帮助有人使用这个简单的代码。

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的简单版本:

var temp = "This is a string.";
var count = (temp.split('is').length - 1);
alert(count);

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

这将返回2。

莱安德罗·巴蒂斯塔:只是正则表达式的问题。

 "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')   ); // ==> 2console.log(   countInstances('ababa', 'aba')   ); // ==> 2console.log(   countInstances('aaabbb', 'ab')   ); // ==> 1

没有人会看到这一点,但偶尔带回递归和箭头函数是很好的(双关语的光荣意图)

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

substr_count从php翻译成Javascript


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}

查看Locutus翻译的PHPsubstr_count函数

 function substrCount( str, x ) {let count = -1, pos = 0;do {pos = str.indexOf( x, pos ) + 1;count++;} while( pos > 0 );return count;}

你可以试试这个

let count = s.length - s.replace(/is/g, "").length;

参数:ustring:超集字符串countChar:子字符串

在JavaScript中计数子字符串出现的函数:

function subStringCount(ustring, countChar){var correspCount = 0;var corresp = false;var amount = 0;var prevChar = null;  
for(var i=0; i!=ustring.length; i++){
if(ustring.charAt(i) == countChar.charAt(0) && corresp == false){corresp = true;correspCount += 1;if(correspCount == countChar.length){amount+=1;corresp = false;correspCount = 0;}prevChar = 1;}else if(ustring.charAt(i) == countChar.charAt(prevChar) && corresp == true){correspCount += 1;if(correspCount == countChar.length){amount+=1;corresp = false;correspCount = 0;prevChar = null;}else{prevChar += 1 ;}}else{corresp = false;correspCount = 0;}}return amount;}
console.log(subStringCount('Hello World, Hello World', 'll'));

var str = 'stackoverflow';var arr = Array.from(str);console.log(arr);
for (let a = 0; a <= arr.length; a++) {var temp = arr[a];var c = 0;for (let b = 0; b <= arr.length; b++) {if (temp === arr[b]) {c++;}
}console.log(`the ${arr[a]} is counted for ${c}`)}

ES2020提供了一个新的MatchAll,可能在这个特定的上下文中有用。

在这里,我们创建一个新的RegExp,请确保将“g”传递给函数。

使用Array.from转换结果并计算长度,根据原始请求者的期望输出返回2。

let strToCheck = RegExp('is', 'g')let matchesReg = "This is a string.".matchAll(strToCheck)console.log(Array.from(matchesReg).length) // 2

第二次迭代更少(仅在子字符串的第一个字母匹配时),但仍然使用2 for循环:

   function findSubstringOccurrences(str, word) {let occurrences = 0;for(let i=0; i<str.length; i++){if(word[0] === str[i]){ // to make it faster and iterate lessfor(let j=0; j<word.length; j++){if(str[i+j] !== word[j]) break;if(j === word.length - 1) occurrences++;}}}return occurrences;}    
console.log(findSubstringOccurrences("jdlfkfomgkdjfomglo", "omg"));
//Try this code
const countSubStr = (str, search) => {let arrStr = str.split('');let i = 0, count = 0;
while(i < arrStr.length){let subStr = i + search.length + 1 <= arrStr.length ?arrStr.slice(i, i+search.length).join('') :arrStr.slice(i).join('');if(subStr === search){count++;arrStr.splice(i, search.length);}else{i++;}}return count;}

一个简单的方法是在所需的单词上拆分字符串,我们要计算出现次数的单词,并从部分数中减去1:

function checkOccurences(string, word) {return string.split(word).length - 1;}const text="Let us see. see above, see below, see forward, see backward, see left, see right until we will be right";const count=countOccurences(text,"see "); // 2
var mystring = 'This is the lorel ipsum text';var mycharArray = mystring.split('');var opArr = [];for(let i=0;i<mycharArray.length;i++){if(mycharArray[i]=='i'){//match the character you want to matchopArr.push(i);}}console.log(opArr); // it will return matching index positionconsole.log(opArr.length); // it will return length
const getLetterMatchCount = (guessedWord, secretWord) => {const secretLetters = secretWord.split('');const guessedLetterSet = new Set(guessedWord);return secretLetters.filter(letter => guessedLetterSet.has(letter)).length;};const str = "rahul";const str1 = "rajendra";
getLetterMatchCount(str, str1)

该函数在三种模式下工作:查找字符串中单个字符的频率,字符串中的连续子字符串,然后如果它确实匹配一个,它就会向前移动到它之后的下一个,第三个与前一个相似,除了它还会计算给定字符串中的交叉子字符串

function substringFrequency(string , substring , conjunction){let indexlet occurenceFrequency  = 0for (let i=0 ; i < string.length  ; i++){index = string.indexOf(substring , i)if (index != -1){if ((substring.length == 1 ) || conjunction == true) {i = index}else {i = index + 1}occurenceFrequency++}else{break}}return (occurenceFrequency)}
console.log(substringFrequency('vvvv' , 'v' ))console.log(substringFrequency('vvvv' , 'vv'))console.log(substringFrequency('vvvv' , 'vv' , true))

我们可以使用jssplit函数,它的长度减1将是出现次数。

var temp = "This is a string.";alert(temp.split('is').length-1);

这是我在2022年使用map()和filter()的解决方案:

string = "Xanthous: A person with yellow hair. Her hair was very xanthous in colour."count = string.split('').map((e,i) => { if(e === 'e') return i;}).filter(Boolean).length

只是为了使用这些函数的乐趣。该示例计算我的字符串中“e”的数量。

这与使用match()函数相同:

(string.match(/e/g)||[]).length

或者简单地说,它的函数是:

string.split('e').length - 1

我认为最好的是使用match(),因为它消耗的资源更少!我的回答只是为了好玩,并表明解决这个问题有很多可能性

这是我的解决方案,希望对别人有帮助

const countOccurence = (string, char) => {const chars = string.match(new RegExp(char, 'g')).lengthreturn chars;}

添加了此优化:

如何计算字符串中出现的字符串?

这可能是这里最快的实现,但如果将“++pos”替换为“pos+=searchFor.length”,它会更快-韩森里克

function occurrences(str_, subStr) {let occurence_count = 0let pos = -subStr.lengthwhile ((pos = str_.indexOf(subStr, pos + subStr.length)) > -1) {occurence_count++}return occurence_count}