programing tip

JavaScript에서 다른 문자열의 모든 발생 색인을 찾는 방법은 무엇입니까?

itbloger 2020. 10. 5. 07:43
반응형

JavaScript에서 다른 문자열의 모든 발생 색인을 찾는 방법은 무엇입니까?


대소 문자를 구분하지 않는 다른 문자열에서 문자열의 모든 발생 위치를 찾으려고합니다.

예를 들어 다음과 같은 문자열이 있습니다.

레바논에서 우쿨렐레를 배웠습니다.

및 검색 문자열 le, 배열을 얻고 싶습니다.

[2, 25, 27, 33]

두 문자열 모두 변수가됩니다. 즉, 값을 하드 코딩 할 수 없습니다.

정규 표현식으로는 쉬운 일이라고 생각했지만, 작동하는 것을 찾기 위해 한동안 고생 한 끝에 운이 없었습니다.

를 사용하여이 작업을 수행하는 방법에 대한 이 예제찾았 .indexOf()지만 확실히 더 간결한 방법이 있어야합니까?


var str = "I learned to play the Ukulele in Lebanon."
var regex = /le/gi, result, indices = [];
while ( (result = regex.exec(str)) ) {
    indices.push(result.index);
}

최신 정보

검색 문자열이 변수 여야한다는 원래 질문에서 발견하지 못했습니다. 를 사용하는이 사건을 처리하기 위해 다른 버전을 작성 indexOf했으므로 시작했던 곳으로 돌아 왔습니다. 주석에서 Wrikken이 지적했듯이 정규식을 사용하는 일반적인 경우에이를 수행하려면 특수 정규식 문자를 이스케이프해야합니다.이 시점에서 정규식 솔루션이 가치가있는 것보다 더 골칫거리가된다고 생각합니다.

function getIndicesOf(searchStr, str, caseSensitive) {
    var searchStrLen = searchStr.length;
    if (searchStrLen == 0) {
        return [];
    }
    var startIndex = 0, index, indices = [];
    if (!caseSensitive) {
        str = str.toLowerCase();
        searchStr = searchStr.toLowerCase();
    }
    while ((index = str.indexOf(searchStr, startIndex)) > -1) {
        indices.push(index);
        startIndex = index + searchStrLen;
    }
    return indices;
}

var indices = getIndicesOf("le", "I learned to play the Ukulele in Lebanon.");

document.getElementById("output").innerHTML = indices + "";
<div id="output"></div>


다음은 정규식 무료 버전입니다.

function indexes(source, find) {
  if (!source) {
    return [];
  }
  // if find is empty string return all indexes.
  if (!find) {
    // or shorter arrow function:
    // return source.split('').map((_,i) => i);
    return source.split('').map(function(_, i) { return i; });
  }
  var result = [];
  for (i = 0; i < source.length; ++i) {
    // If you want to search case insensitive use 
    // if (source.substring(i, i + find.length).toLowerCase() == find) {
    if (source.substring(i, i + find.length) == find) {
      result.push(i);
    }
  }
  return result;
}

indexes("I learned to play the Ukulele in Lebanon.", "le")

편집 : 'aaaa'및 'aa'와 같은 문자열을 일치시켜 [0, 2]를 찾으려면이 버전을 사용하십시오.

function indexes(source, find) {
  if (!source) {
    return [];
  }
  if (!find) {
      return source.split('').map(function(_, i) { return i; });
  }
  var result = [];
  var i = 0;
  while(i < source.length) {
    if (source.substring(i, i + find.length) == find) {
      result.push(i);
      i += find.length;
    } else {
      i++;
    }
  }
  return result;
}

당신은 확실히 할 수 있습니다!

//make a regular expression out of your needle
var needle = 'le'
var re = new RegExp(needle,'gi');
var haystack = 'I learned to play the Ukulele';

var results = new Array();//this is the results you want
while (re.exec(haystack)){
  results.push(re.lastIndex);
}

편집 : RegExp 철자 배우기

또한 바늘의 끝이 시작이 아니라 끝이 아니라는 것을 알려주기 때문에 이것이 정확히 원하는 것이 아니라는 것을 깨달았 lastIndex습니다. 가깝습니다 re.lastIndex-needle.length. 결과 배열로 밀어 넣을 수 있습니다 .

편집 : 링크 추가

@Tim Down의 답변은 RegExp.exec ()의 결과 객체를 사용하고 모든 Javascript 리소스는 사용에 대해 광택이 있습니다 (일치하는 문자열을 제공하는 것 제외). 그래서 그가를 사용할 때 result.index그것은 일종의 이름없는 Match Object입니다. execMDC 설명에서 실제로이 개체를 상당히 자세하게 설명합니다.


모든 경기의 위치를 ​​찾고 싶다면 약간의 해킹을 알려 드리고자합니다.

haystack = 'I learned to play the Ukulele in Lebanon.'
needle = 'le'
splitOnFound = haystack.split(needle).map(function (culm) {
  return this.pos += culm.length + needle.length
}, {pos: -needle.length}).slice(0, -1)

가변 길이의 RegExp가있는 경우에는 적용되지 않을 수 있지만 일부는 유용 할 수 있습니다.


String.prototype.match를 사용하십시오 .

Here is an example from the MDN docs itself:

var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matches_array = str.match(regexp);

console.log(matches_array);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']

Follow the answer of @jcubic, his solution caused a small confuse for my case
For example var result = indexes('aaaa', 'aa') it will return [0, 1, 2] instead of [0, 2]
So I updated a bit his solution as below to match my case

function indexes(text, subText, caseSensitive) {
    var _source = text;
    var _find = subText;
    if (caseSensitive != true) {
        _source = _source.toLowerCase();
        _find = _find.toLowerCase();
    }
    var result = [];
    for (var i = 0; i < _source.length;) {
        if (_source.substring(i, i + _find.length) == _find) {
            result.push(i);
            i += _find.length;  // found a subText, skip to next position
        } else {
            i += 1;
        }
    }
    return result;
}

Here is a simple Code

function getIndexOfSubStr(str, serchToken, preIndex, output){
		 var result = str.match(serchToken);
     if(result){
     output.push(result.index +preIndex);
     str=str.substring(result.index+serchToken.length);
     getIndexOfSubStr(str, serchToken, preIndex, output)
     }
     return output;
  };

var str = "my name is 'xyz' and my school name is 'xyz' and my area name is 'xyz' ";
var  serchToken ="my";
var preIndex = 0;

console.log(getIndexOfSubStr(str, serchToken, preIndex, []));


Thanks for all the replies. I went through all of them and came up with a function that gives the first an last index of each occurrence of the 'needle' substring . I am posting it here in case it will help someone.

Please note, it is not the same as the original request for only the beginning of each occurrence. It suits my usecase better because you don't need to keep the needle length.

function findRegexIndices(text, needle, caseSensitive){
  var needleLen = needle.length,
    reg = new RegExp(needle, caseSensitive ? 'gi' : 'g'),
    indices = [],
    result;

  while ( (result = reg.exec(text)) ) {
    indices.push([result.index, result.index + needleLen]);
  }
  return indices
}

the below code will do the job for you :

function indexes(source, find) {
  var result = [];
  for(i=0;i<str.length; ++i) {
    // If you want to search case insensitive use 
    // if (source.substring(i, i + find.length).toLowerCase() == find) {
    if (source.substring(i, i + find.length) == find) {
      result.push(i);
    }
  }
  return result;
}

indexes("hello, how are you", "ar")

function countInString(searchFor,searchIn){

 var results=0;
 var a=searchIn.indexOf(searchFor)

 while(a!=-1){
   searchIn=searchIn.slice(a*1+searchFor.length);
   results++;
   a=searchIn.indexOf(searchFor);
 }

return results;

}

참고URL : https://stackoverflow.com/questions/3410464/how-to-find-indices-of-all-occurrences-of-one-string-in-another-in-javascript

반응형