如何计算string中的string发生?

如何计算特定string在另一个string中出现的次数。 例如,这是我正在尝试在Javascript中执行的操作:

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

正则expression式中的g (简称全局 )表示search整个string,而不是仅仅查找第一个string:

 var temp = "This is a string."; var count = (temp.match(/is/g) || []).length; console.log(count); 
 /** 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 `----´ 

unit testing

基准

我已经做了一个基准testing,我的function比通过gumbo发布的正则expression式匹配函数快了10倍。 在我的testingstring是25个字符的长度。 有两个字符“o”。 我在Safari中执行了100万次。

Safari 5.1

基准testing>总共执行时间:5617毫秒(正则expression式)

基准testing>总共执行时间:881毫秒(我的function快6.4倍)

Firefox 4

基准testing>总共执行时间:8547毫秒(Rexexp)

基准testing>执行时间总计:634毫秒(我的function快13.5倍)


编辑:我所做的更改

  • caching的string长度

  • 添加types转换为string。

  • 添加了可选的“allowOverlapping”参数

  • 修正了“”空子串情况下的正确输出。

要旨

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

你可以试试这个:

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

我的解决scheme

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

你可以使用match来定义这样的function:

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

这是最快的function!

为什么它更快?

  • 不检查字符char(有1个例外)
  • 使用一段时间,并增加1 var(char count var)与for循环检查长度并递增2个variables(通常是var i和var与char数量)
  • 使用WAY减less变数
  • 不使用正则expression式!
  • 使用(希望)高度优化的function
  • 所有的操作都是尽可能的组合在一起,避免由于多个操作而造成的减速

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

由于计数器,long var名称和1 var的滥用,这个比较慢。

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

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

编辑:(2013/12/16)

切勿使用Opera 12.16或更高版本! 它将比正则expression式解决scheme差不多多2.5倍!

在chrome上,这个解决scheme将需要14ms到20ms之间的1,000,000个字符。

正则expression式解决scheme需要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'); 

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

注意:如果你想让这个函数计算多于一个字符,把c=(c+'')[0]改成c=c+''

只是代码打高尔夫上述解决scheme:-)

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

非正则expression式版本:

  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 temp = "This is a string."; console.log((temp.match(new RegExp("is", "g")) || []).length); 

我认为正则expression式的目的与indexOf有很大不同。 indexOf只需在正则expression式中查找某个string的发生,就可以使用[AZ]这样的通配符,这意味着它将在单词中find任何大写字母,而不用说明实际的字符。

例:

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

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

这将返回2。

超级老二,但我今天需要做这样的事情,只想到后来检查。 为我工作得非常快。

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

请参阅: – 计数一个子串出现在string中的逐步解释。

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

标点符号正则expression式来自: https : //stackoverflow.com/a/25575009/497745 ( 我如何使用正则expression式从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; } 

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

对于任何未来发现此线程的人来说,注意接受的答案不会总是返回正确的值,因为它会阻塞正则expression式运算符(如$和) . 。 这是一个更好的版本,可以处理任何针头:

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

尝试一下

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

简单的版本没有正则expression式:

 var temp = "This is a string."; var count = (temp.split('is').length - 1); alert(count); 
 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)); 

现在这是我遇到的一个非常古老的线程,但许多人已经推出了他们的答案,这是我的希望,以帮助这个简单的代码的人。

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

回答Leandro Batista:只是正则expression式的一个问题。

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

尝试这个:

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