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

2022-08-30 04:10:01

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

例如,给定字符串:

I learned to play the Ukulele in Lebanon.

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

[2, 25, 27, 33]

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

我认为这对于正则表达式来说是一件容易的事,但是在努力寻找一个有效的正则表达式之后,我没有运气。

我发现了这个例子,说明如何使用来完成此操作,但肯定必须有更简洁的方法才能做到这一点?.indexOf()


答案 1
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);
}

更新

我在原始问题中未能发现搜索字符串必须是变量。我写了另一个版本来处理这种情况,它使用,所以你回到了你开始的地方。正如Wrikken在评论中指出的那样,要对正则表达式的一般情况执行此操作,您需要转义特殊的正则表达式字符,此时我认为正则表达式解决方案变得更加令人头疼,而不是它的价值。indexOf

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>

答案 2

一个使用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]

如果你担心在一行中做一个点差和一个,我用一个循环运行它一百万次迭代(使用你的字符串)。一个衬垫平均为1420ms,而我的机器上的平均速度为1150ms。这不是一个微不足道的区别,但是如果你只做一些比赛,一个衬里会很好。map()for...offor...of

在caniuse上看到匹配所有