source

문자열에서 문자열 오카렌스를 계산하는 방법

nicesource 2022. 12. 24. 16:54
반응형

문자열에서 문자열 오카렌스를 계산하는 방법

특정 문자열이 다른 문자열에서 발생하는 횟수를 카운트하려면 어떻게 해야 합니까?예를 들어 Javascript에서는 다음과 같은 작업을 수행하려고 합니다.

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

g정규 표현(글로벌의 줄임말)에서는 첫 번째 오카렌스를 찾는 것뿐만 아니라 문자열 전체를 검색하도록 되어 있습니다.이것은 일치합니다is 2회:

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

일치:

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

유닛 테스트

벤치마크

벤치마크 테스트를 해봤는데 gumbo가 올린 regexp 매치 기능보다 10배 이상 빠릅니다.내 테스트 문자열은 25자 길이이고 'o'가 2개 발생합니다.나는 사파리에서 100,000번 실행했다.

Safari 5.1

벤치마크> 총 실행 시간: 5617 ms (regexp)

벤치마크> 총 실행시간: 881 ms (기능이 6.4배 빠름)

파이어폭스 4

벤치마크> 총 실행 시간: 8547 ms (Rexexp)

벤치마크> 총 실행시간: 634 ms (기능 13.5배 고속)


편집: 변경 사항

  • 캐시된 서브스트링 길이

  • 문자열에 유형 캐스팅이 추가되었습니다.

  • 옵션 'allowOverlapping' 매개 변수가 추가되었습니다.

  • 빈 서브스트링 케이스의 올바른 출력을 수정했습니다.

기스트

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

다음과 같이 시험해 보십시오.

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

솔루션:

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「 」 「 」 능의 :

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

비 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

String.prototype.Count = function (find) {
    return this.split(find).length - 1;
}

console.log("This is a string.".Count("is"));

2가 반환됩니다.

여기 가장 빠른 기능이 있어요!

왜 더 빨라?

  • char by chars (1개의 예외)를 체크하지 않음
  • 길이 확인 및 2개의 변수 증가(일반적으로 vari 및 var가 있는 변수)를 사용하여 a에 대해 1 var(char count var)를 증가시킵니다.
  • WAY를 덜 사용합니다.
  • 정규식을 사용하지 않습니다!
  • (바람직하게) 고도로 최적화된 기능 사용
  • 모든 작업을 가능한 한 조합하여 여러 작업으로 인한 속도 저하 방지

    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 이상에서는 사용하지 마십시오!regex 솔루션보다 약 2.5배 더 많은 시간이 소요됩니다!

크롬의 경우 100만 글자에 14ms~20ms가 소요된다.

regex 솔루션은 같은 양으로 11~14ms가 소요됩니다.

)String.prototype은 약 10됩니다.)10~13밀리초면 됩니다.

사용되는 코드는 다음과 같습니다.

    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이 되어야 합니다!

이 이상으로 는, 「」의 「2」의 「2」의 「」, 「2」의 「」의 「2」의 「」의 「」를 참조해 주세요.c=(c+'')[0]c=c+''

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

은 regex와 많이 것 요.indexOfindexOf에서는 특정 문자열의 .regex 에서는 를 사용할 수 .[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);

간단한 방법은 발생 횟수를 계산하는 단어인 필수 단어에서 문자열을 분할하고 부분 수에서 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

너무 낡았지만, 오늘 이런 일을 해야 해서 나중에 SO를 확인해야겠다고 생각했어요.나한테는 꽤 빨리 되는군

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

스텝 바이 스텝에 대해서는, 「count a substring 」를 참조해 주세요.

upon@Vittim.us 구축은 위의 답변입니다.나는 그의 방법이 나에게 주는 컨트롤이 마음에 들어, 확장하기 쉽지만, 나는 대소문자를 구분하지 않고 구두점을 지원하는 전체 단어에 매칭을 제한할 필요가 있었다.(예: "목욕"은 "목욕"에 있지만 "목욕"에는 없습니다.)

구두점 regex는 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;
}

만약 버그나 개선사항이 발견되면 이 답변을 수정하고 수정해 주십시오.

이 할 경우 하는 것은 .는 " " "와 같은 초크되기 입니다.이는 다음과 같은 regex 연산자에 의해 초크되기 때문입니다.$ ★★★★★★★★★★★★★★★★★」.다음은 어떤 바늘도 다룰 수 있는 더 나은 버전입니다.

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>

regex가 없는 단순 버전:

var temp = "This is a string.";

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

alert(count);

아무도 볼 수 없지만, 가끔 재귀와 화살표 기능을 되살리는 것이 좋습니다(명예로운 의도).

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

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

이것은 매우 오래된 이야기이지만, 많은 사람들이 그들의 대답을 강요하고 있기 때문에, 여기 이 간단한 코드로 누군가를 돕기를 희망하고 있습니다.

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를 사용하지 않는 것을 선호합니다(사용하는 것이 싫습니다).

 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;

js를 사용할 수 있습니다.split함수, 길이에서 1을 뺀 값이 발생 횟수가 됩니다.

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

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


substr_countphp에서 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의 Php의 subst_count 함수를 확인하십시오.

파라미터: urstring: superset string count Char: substring

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}`)
}

(서브스트링의 첫 글자가 일치하는 경우에만) 두 번째 반복 횟수가 적지만 루프의 경우 2를 사용합니다.

   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 less
                for(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"));

언급URL : https://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string

반응형