如何在 JavaScript 中查找一个字符串在另一个字符串中所有出现的索引?

发布于 2024-09-13 06:50:38 字数 513 浏览 1 评论 0原文

我试图找到一个字符串在另一个字符串中所有出现的位置,不区分大小写。

例如,给定字符串:

I learned to play the Ukulele in Lebanon.

和搜索字符串le,我想获取数组:

[2, 25, 27, 33]

两个字符串都是变量 - 即,我无法对它们的值进行硬编码。

我认为这对于正则表达式来说是一项简单的任务,但是在努力寻找一个可行的方法之后,我没有运气。

我找到了 这个示例,说明如何使用 完成此操作.indexOf(),但肯定有一个更简洁的方法来做到这一点吗?

I'm trying to find the positions of all occurrences of a string in another string, case-insensitive.

For example, given the string:

I learned to play the Ukulele in Lebanon.

and the search string le, I want to obtain the array:

[2, 25, 27, 33]

Both strings will be variables - i.e., I can't hard-code their values.

I figured that this was an easy task for regular expressions, but after struggling for a while to find one that would work, I've had no luck.

I found this example of how to accomplish this using .indexOf(), but surely there has to be a more concise way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

简单 2024-09-20 06:50:38
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>

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

UPDATE

I failed to spot in the original question that the search string needs to be a variable. I've written another version to deal with this case that uses indexOf, so you're back to where you started. As pointed out by Wrikken in the comments, to do this for the general case with regular expressions you would need to escape special regex characters, at which point I think the regex solution becomes more of a headache than it's worth.

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>

浮萍、无处依 2024-09-20 06:50:38

使用 String.prototype.matchAll 的一个衬垫 (ES2020):

[...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index)

使用你的值:

const sourceStr = 'I learned to play the Ukulele in Lebanon.';
const searchStr = 'le';
const indexes = [...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index);
console.log(indexes); // [2, 25, 27, 33]

如果你担心在一行中进行展开和 map(),我用 for 运行它...of 循环一百万次迭代(使用您的字符串)。在我的机器上,一个衬垫平均为 1420 毫秒,而 for...of 平均为 1150 毫秒。这并不是一个微不足道的差异,但如果您只进行少量比赛,那么单衬管就可以很好地工作。

查看 caniuse 上的 matchAll

One liner using String.prototype.matchAll (ES2020):

[...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index)

Using your values:

const sourceStr = 'I learned to play the Ukulele in Lebanon.';
const searchStr = 'le';
const indexes = [...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index);
console.log(indexes); // [2, 25, 27, 33]

If you're worried about doing a spread and a map() in one line, I ran it with a for...of loop for a million iterations (using your strings). The one liner averages 1420ms while the for...of averages 1150ms on my machine. That's not an insignificant difference, but the one liner will work fine if you're only doing a handful of matches.

See matchAll on caniuse

旧故 2024-09-20 06:50:38

你一定可以做到这一点!

//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 时,这是某种未命名的匹配对象。在 exec 的 MDC 描述中,他们实际上在不错的细节。

You sure can do this!

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

Edit: learn to spell RegExp

Also, I realized this isn't exactly what you want, as lastIndex tells us the end of the needle not the beginning, but it's close - you could push re.lastIndex-needle.length into the results array...

Edit: adding link

@Tim Down's answer uses the results object from RegExp.exec(), and all my Javascript resources gloss over its use (apart from giving you the matched string). So when he uses result.index, that's some sort of unnamed Match Object. In the MDC description of exec, they actually describe this object in decent detail.

挽清梦 2024-09-20 06:50:38

这是正则表达式免费版本:

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

Here is regex free version:

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

EDIT: and if you want to match strings like 'aaaa' and 'aa' to find [0, 2] use this version:

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;
}
∞觅青森が 2024-09-20 06:50:38

我参加聚会有点晚了(差不多 10 年零 2 个月),但未来的程序员的一种方法是使用 while 循环和 indexOf()

let haystack = "I learned to play the Ukulele in Lebanon.";
let needle = "le";
let pos = 0; // Position Ref
let result = []; // Final output of all index's.
let hayStackLower = haystack.toLowerCase();

// Loop to check all occurrences 
while (hayStackLower.indexOf(needle, pos) != -1) {
  result.push(hayStackLower.indexOf(needle , pos));
  pos = hayStackLower.indexOf(needle , pos) + 1;
}

console.log("Final ", result); // Returns all indexes or empty array if not found

I am a bit late to the party (by almost 10 years, 2 months), but one way for future coders is to do it using while loop and indexOf()

let haystack = "I learned to play the Ukulele in Lebanon.";
let needle = "le";
let pos = 0; // Position Ref
let result = []; // Final output of all index's.
let hayStackLower = haystack.toLowerCase();

// Loop to check all occurrences 
while (hayStackLower.indexOf(needle, pos) != -1) {
  result.push(hayStackLower.indexOf(needle , pos));
  pos = hayStackLower.indexOf(needle , pos) + 1;
}

console.log("Final ", result); // Returns all indexes or empty array if not found
你又不是我 2024-09-20 06:50:38
const findAllOccurrences = (str, substr) => {
  str = str.toLowerCase();
  
  let result = [];

  let idx = str.indexOf(substr)
  
  while (idx !== -1) {
    result.push(idx);
    idx = str.indexOf(substr, idx+1);
  }
  return result;
}

console.log(findAllOccurrences('I learned to play the Ukulele in Lebanon', 'le'));
const findAllOccurrences = (str, substr) => {
  str = str.toLowerCase();
  
  let result = [];

  let idx = str.indexOf(substr)
  
  while (idx !== -1) {
    result.push(idx);
    idx = str.indexOf(substr, idx+1);
  }
  return result;
}

console.log(findAllOccurrences('I learned to play the Ukulele in Lebanon', 'le'));
转瞬即逝 2024-09-20 06:50:38

如果你只是想找到所有比赛的位置,我想告诉你一个小窍门:

var 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); // {pos: ...} – Object wich is used as this

console.log(splitOnFound);

如果您有可变长度的正则表达式,它可能不适用,但对于某些人来说可能会有所帮助。

这是区分大小写的。对于不区分大小写的情况,请先使用 String.toLowerCase 函数。

If you just want to find the position of all matches I'd like to point you to a little hack:

var 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); // {pos: ...} – Object wich is used as this

console.log(splitOnFound);

It might not be applikable if you have a RegExp with variable length but for some it might be helpful.

This is case sensitive. For case insensitivity use String.toLowerCase function before.

写给空气的情书 2024-09-20 06:50:38

我会推荐蒂姆的答案。但是,@blazs 的此评论指出“假设 searchStr=aaastr=aaaaaa,那么您的代码将只找到 2 次,而不是找到 4 次。你在循环中通过 searchStr.length 进行跳过。”,通过查看 Tim 的代码,这是正确的,特别是这里的这一行: startIndex = index + searchStrLen; Tim 的代码将无法找到正在搜索的字符串的实例,其长度在其自身范围内。所以,我修改了蒂姆的答案:

function getIndicesOf(searchStr, str, caseSensitive) {
    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 + 1;
    }
    return indices;
}
var searchStr = prompt("Enter a string.");
var str = prompt("What do you want to search for in the string?");
var indices = getIndicesOf(str, searchStr);

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

如果我有一个 aaaaaa 的 str 和一个aaa 的 searchStr。

PS 如果有人想在代码中添加注释来解释代码的工作原理,请说出来,我很乐意回复该请求。

I would recommend Tim's answer. However, this comment by @blazs states "Suppose searchStr=aaa and that str=aaaaaa. Then instead of finding 4 occurences your code will find only 2 because you're making skips by searchStr.length in the loop.", which is true by looking at Tim's code, specifically this line here: startIndex = index + searchStrLen; Tim's code would not be able to find an instance of the string that's being searched that is within the length of itself. So, I've modified Tim's answer:

function getIndicesOf(searchStr, str, caseSensitive) {
    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 + 1;
    }
    return indices;
}
var searchStr = prompt("Enter a string.");
var str = prompt("What do you want to search for in the string?");
var indices = getIndicesOf(str, searchStr);

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

Changing it to + 1 instead of + searchStrLen will allow the index 1 to be in the indices array if I have an str of aaaaaa and a searchStr of aaa.

P.S. If anyone would like comments in the code to explain how the code works, please say so, and I'll be happy to respond to the request.

零度℉ 2024-09-20 06:50:38

感谢您的所有回复。我遍历了所有这些,并提出了一个函数,该函数给出了每次出现 'needle' 子字符串的第一个和最后一个索引。我将其发布在这里,以防它对某人有所帮助。

请注意,它与仅每次出现的开头的原始请求不同。它更适合我的用例,因为您不需要保持针的长度。

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
}

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
}
极致的悲 2024-09-20 06:50:38

这是一个简单的代码片段:

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

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

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

Here is a simple code snippet:

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

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

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

恋竹姑娘 2024-09-20 06:50:38

这就是我通常用来根据字符串位置获取字符串索引的方法。

我传递以下参数:

search:搜索位置的字符串

find:查找 位置的字符串

(默认为“全部”):查找字符串在搜索字符串中出现的位置

(如果为“all”,则返回完整的索引数组)

(如果为“last”,则返回最后一个位置)

function stringIndex (search, find, position = "all") {
    
    var currIndex = 0, indexes = [], found = true;
    
    while (found) {        
        var searchIndex = search.indexOf(find);
        if (searchIndex > -1) {
            currIndex += searchIndex + find.length; 
            search = search.substr (searchIndex + find.length);
            indexes.push (currIndex - find.length);
        } else found = false; //no other string to search for - exit from while loop   
    }
    
    if (position == 'all') return indexes;
    if (position > indexes.length -1) return [];
    
    position = (position == "last") ? indexes.length -1 : position;
    
    return indexes[position];        
}

//Example:
    
var myString = "Joe meets Joe and together they go to Joe's house";
console.log ( stringIndex(myString, "Joe") ); //0, 10, 38
console.log ( stringIndex(myString, "Joe", 1) ); //10
console.log ( stringIndex(myString, "Joe", "last") ); //38
console.log ( stringIndex(myString, "Joe", 5) ); //[]

This is what I usually use to get a string index also according to its position.

I pass following parameters:

search: the string where to search for

find: the string to find

position ('all' by default): the position by which the find string appears in search string

(if 'all' it returns the complete array of indexes)

(if 'last' it returns the last position)

function stringIndex (search, find, position = "all") {
    
    var currIndex = 0, indexes = [], found = true;
    
    while (found) {        
        var searchIndex = search.indexOf(find);
        if (searchIndex > -1) {
            currIndex += searchIndex + find.length; 
            search = search.substr (searchIndex + find.length);
            indexes.push (currIndex - find.length);
        } else found = false; //no other string to search for - exit from while loop   
    }
    
    if (position == 'all') return indexes;
    if (position > indexes.length -1) return [];
    
    position = (position == "last") ? indexes.length -1 : position;
    
    return indexes[position];        
}

//Example:
    
var myString = "Joe meets Joe and together they go to Joe's house";
console.log ( stringIndex(myString, "Joe") ); //0, 10, 38
console.log ( stringIndex(myString, "Joe", 1) ); //10
console.log ( stringIndex(myString, "Joe", "last") ); //38
console.log ( stringIndex(myString, "Joe", 5) ); //[]
故事与诗 2024-09-20 06:50:38

嗨朋友们,这只是使用reduce和辅助方法查找匹配短语索引的另一种方法。当然 RegExp 更方便,也许内部是这样实现的。我希望你觉得它有用。

function findIndexesOfPhraseWithReduce(text,phrase) {
      //将文本转换为数组以便能够操作。
          const arrayOfText = [...文本];

      /* 该函数接受字符数组并
      来自reduce方法的搜索短语和起始索引
      并计算给定短语长度的结尾,然后进行切片
      并连接字符并将其与短语进行比较。
      并返回 True 或 False */

         函数 isMatch(数组、短语、开始) {
         const end = 开始 + 短语.length;
         return (array.slice(start, end).join('')).toLowerCase() === 
               短语.toLowerCase();
         }

    /* 这里我们减少字符数组并测试每个字符
    使用 isMach 函数,它接受“当前索引”并匹配短语
    以及从当前索引开始的后续字符
    以短语的最后一个字符结束(短语的长度)。 */

        return arrayOfText.reduce((acc, item, index) => isMatch(arrayOfText, 短语, 
        指数) ? [...acc, 索引] : acc, []);
}

findIndexesOfPhraseWithReduce("我在黎巴嫩学会了弹尤克里里琴。", "le");
function findIndexesOfPhraseWithReduce(text, phrase) {
     
         const arrayOfText = [...text];
         function isMatch(array, phrase, start) {
         const end = start + phrase.length;
         return (array.slice(start, end).join('')).toLowerCase() === 
               phrase.toLowerCase();
         }
        return arrayOfText.reduce((acc, item, index) => isMatch(arrayOfText, phrase, 
        index) ? [...acc, index] : acc, []);
}

console.log(findIndexesOfPhraseWithReduce("I learned to play the Ukulele in Lebanon.", "le"));

Hi friends this is just another way of finding indexes of matching phrase using reduce and a helper method. Of course RegExp is more convenient and perhaps is internally implemented somehow like this. I hope you find it useful.

function findIndexesOfPhraseWithReduce(text, phrase) {
      //convert text to array so that be able to manipulate.
          const arrayOfText = [...text];

      /* this function takes the array of characters and
      the search phrase and start index which comes from reduce method
      and calculates the end with length of the given phrase then slices
      and joins characters and compare it whith phrase.
      and returns True Or False */

         function isMatch(array, phrase, start) {
         const end = start + phrase.length;
         return (array.slice(start, end).join('')).toLowerCase() === 
               phrase.toLowerCase();
         }

    /* here we reduce the array of characters and test each character
    with isMach function which takes "current index" and matches the phrase
    with the subsequent character which starts from current index and
    ends at the last character of phrase(the length of phrase). */

        return arrayOfText.reduce((acc, item, index) => isMatch(arrayOfText, phrase, 
        index) ? [...acc, index] : acc, []);
}

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

function findIndexesOfPhraseWithReduce(text, phrase) {
     
         const arrayOfText = [...text];
         function isMatch(array, phrase, start) {
         const end = start + phrase.length;
         return (array.slice(start, end).join('')).toLowerCase() === 
               phrase.toLowerCase();
         }
        return arrayOfText.reduce((acc, item, index) => isMatch(arrayOfText, phrase, 
        index) ? [...acc, index] : acc, []);
}

console.log(findIndexesOfPhraseWithReduce("I learned to play the Ukulele in Lebanon.", "le"));

浅笑轻吟梦一曲 2024-09-20 06:50:38

检查这个解决方案,它也能够找到相同的字符串,如果缺少或不正确,请告诉我。

function indexes(source, find) {
    if (!source) {
      return [];
    }
    if (!find) {
        return source.split('').map(function(_, i) { return i; });
    }
    source = source.toLowerCase();
    find = find.toLowerCase();
    var result = [];
    var i = 0;
    while(i < source.length) {
      if (source.substring(i, i + find.length) == find)
        result.push(i++);
      else
        i++
    }
    return result;
  }
  console.log(indexes('aaaaaaaa', 'aaaaaa'))
  console.log(indexes('aeeaaaaadjfhfnaaaaadjddjaa', 'aaaa'))
  console.log(indexes('wordgoodwordgoodgoodbestword', 'wordgood'))
  console.log(indexes('I learned to play the Ukulele in Lebanon.', 'le'))

Check this solution which will able to find same character string too, let me know if something missing or not right.

function indexes(source, find) {
    if (!source) {
      return [];
    }
    if (!find) {
        return source.split('').map(function(_, i) { return i; });
    }
    source = source.toLowerCase();
    find = find.toLowerCase();
    var result = [];
    var i = 0;
    while(i < source.length) {
      if (source.substring(i, i + find.length) == find)
        result.push(i++);
      else
        i++
    }
    return result;
  }
  console.log(indexes('aaaaaaaa', 'aaaaaa'))
  console.log(indexes('aeeaaaaadjfhfnaaaaadjddjaa', 'aaaa'))
  console.log(indexes('wordgoodwordgoodgoodbestword', 'wordgood'))
  console.log(indexes('I learned to play the Ukulele in Lebanon.', 'le'))

俏︾媚 2024-09-20 06:50:38

按照@jcubic的回答,他的解决方案对我的案例造成了一些混乱
例如 var result =indexes('aaaa', 'aa') 将返回 [0, 1, 2] 而不是 [0, 2]代码>
所以我更新了他的解决方案如下以匹配我的情况

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

Follow the answer of @jcubic, his solution caused a small confusion for my case
For example var result = indexes('aaaa', 'aa') 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;
}
初熏 2024-09-20 06:50:38

这是我的代码(使用搜索和切片方法)

    let s = "I learned to play the Ukulele in Lebanon"
    let sub = 0 
    let matchingIndex = []
    let index = s.search(/le/i)
    while( index >= 0 ){
       matchingIndex.push(index+sub);
       sub = sub + ( s.length - s.slice( index+1 ).length )
       s = s.slice( index+1 )
       index = s.search(/le/i)
    } 
    console.log(matchingIndex)

Here's my code (using search and slice methods)

    let s = "I learned to play the Ukulele in Lebanon"
    let sub = 0 
    let matchingIndex = []
    let index = s.search(/le/i)
    while( index >= 0 ){
       matchingIndex.push(index+sub);
       sub = sub + ( s.length - s.slice( index+1 ).length )
       s = s.slice( index+1 )
       index = s.search(/le/i)
    } 
    console.log(matchingIndex)

郁金香雨 2024-09-20 06:50:38

如果您无论如何都想循环生成器,那么这似乎是使用生成器的好时机。

function* findAllMatches(
  str,
  substr,
  caseInsensitive
) {
  const s = caseInsensitive ? str.toLowerCase() : str;
  const m = caseInsensitive ? substr.toLowerCase() : substr;
  let idx = -1;

  while ((idx = s.indexOf(m, idx + 1)) !== -1) {
    yield idx;
  }
}

const str = "I learned to play the Ukulele in Lebanon"

const matches = findAllMatches(str, "le", true);
for (const idx of matches) {
  console.log(idx);
}

// Or if you really want an array
const matches2 = Array.from(findAllMatches(str, "le", true))
console.log('As an array:', matches2);

This seems like a good time to use generators if your intention is to loop over them anyway.

function* findAllMatches(
  str,
  substr,
  caseInsensitive
) {
  const s = caseInsensitive ? str.toLowerCase() : str;
  const m = caseInsensitive ? substr.toLowerCase() : substr;
  let idx = -1;

  while ((idx = s.indexOf(m, idx + 1)) !== -1) {
    yield idx;
  }
}

const str = "I learned to play the Ukulele in Lebanon"

const matches = findAllMatches(str, "le", true);
for (const idx of matches) {
  console.log(idx);
}

// Or if you really want an array
const matches2 = Array.from(findAllMatches(str, "le", true))
console.log('As an array:', matches2);

⒈起吃苦の倖褔 2024-09-20 06:50:38

感谢 Victor他/她回答。我尝试改进他/她的答案:

function findAllOccurrences(str: string, subStr: string) {
  const result: number[] = []
  for (let i = str.indexOf(subStr, 0); i !== -1 ; i = str.indexOf(subStr, i + 1)) result.push(i)
  return result
}

Thank Victor for his/her answer. I tried to improve his/her answer:

function findAllOccurrences(str: string, subStr: string) {
  const result: number[] = []
  for (let i = str.indexOf(subStr, 0); i !== -1 ; i = str.indexOf(subStr, i + 1)) result.push(i)
  return result
}
魔法唧唧 2024-09-20 06:50:38
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;

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

}
孤千羽 2024-09-20 06:50:38

下面的代码将为您完成这项工作:

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

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")
眉黛浅 2024-09-20 06:50:38

使用 String.prototype.match

以下是 MDN 文档本身的示例:

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

Use 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']
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文