如何获取字符串中的第n次出现?

IT技术 javascript
2021-02-02 09:07:13

我想得到这样的事情2nd发生的起始位置ABC

var string = "XYZ 123 ABC 456 ABC 789 ABC";
getPosition(string, 'ABC', 2) // --> 16

你会怎么做?

6个回答

const string = "XYZ 123 ABC 456 ABC 789 ABC";

function getPosition(string, subString, index) {
  return string.split(subString, index).join(subString).length;
}

console.log(
  getPosition(string, 'ABC', 2) // --> 16
)

我其实不喜欢这个答案。给定一个无界长度输入,它不必要地创建一个无界长度数组,然后将其中的大部分扔掉。迭代地使用fromIndex参数会更快、更有效String.indexOf
2021-03-25 09:07:13
如果 <i出现< 这将为您提供字符串的长度m也就是说,getPosition("aaaa","a",5)给出4,也一样getPosition("aaaa","a",72)我认为在这些情况下你想要 -1。var ret = str.split(m, i).join(m).length; return ret >= str.length ? -1 : ret;您可能还希望赶上i <= 0return ret >= str.length || i <= 0 ? -1 : ret;
2021-03-30 09:07:13
function getPosition(str, m, i) { return str.split(m, i).join(m).length; }
2021-04-01 09:07:13
如果您指定每个参数的含义,我会很好。
2021-04-07 09:07:13
@Foreever 我只是简单地实现了 OP 定义的函数
2021-04-10 09:07:13

您还可以在不创建任何数组的情况下使用字符串 indexOf。

第二个参数是开始寻找下一个匹配项的索引。

function nthIndex(str, pat, n){
    var L= str.length, i= -1;
    while(n-- && i++<L){
        i= str.indexOf(pat, i);
        if (i < 0) break;
    }
    return i;
}

var s= "XYZ 123 ABC 456 ABC 789 ABC";

nthIndex(s,'ABC',3)

/*  returned value: (Number)
24
*/
根据jsperf,这种方法比公认的答案要快得多
2021-03-19 09:07:13
荒谬的是,这不是 JS 的内置功能。
2021-03-24 09:07:13
我更喜欢这个而不是接受的答案,因为当我测试第二个不存在的实例时,另一个答案返回第一个字符串的长度,这个字符串返回-1。投赞成票,谢谢。
2021-04-01 09:07:13
我喜欢这个版本是因为长度缓存而不是扩展 String 原型。
2021-04-03 09:07:13
的递增i可以减少混淆:var i; for (i = 0; n > 0 && i !== -1; n -= 1) { i = str.indexOf(pat, /* fromIndex */ i ? (i + 1) : i); } return i;
2021-04-09 09:07:13

根据 kennebec 的回答,我创建了一个原型函数,如果没有找到第 n 次出现而不是 0,它将返回 -1。

String.prototype.nthIndexOf = function(pattern, n) {
    var i = -1;

    while (n-- && i++ < this.length) {
        i = this.indexOf(pattern, i);
        if (i < 0) break;
    }

    return i;
}
尤其是在做原型时。当然,没有人可能会使用那个特定的方法名称,尽管允许自己这样做会造成一个坏习惯。不同的关键,虽然例如:总是在做围数据时的SQLINSERT作为mysqli_real_escape_string防止单引号黑客。许多专业编码不仅仅是拥有良好的习惯,而且还了解为什么这些习惯很重要。:-)
2021-03-23 09:07:13
从来没有 使用驼峰为特征的最终适应本地本原型可能会无意中成为覆盖。在这种情况下,我建议使用所有小写字母和下划线(URL 的破折号):String.prototype.nth_index_of即使你认为你的名字足够独特和疯狂,世界也会证明它可以而且会做得更疯狂。
2021-03-29 09:07:13
不要扩展字符串原型。
2021-04-01 09:07:13

因为递归总是答案。

function getPosition(input, search, nth, curr, cnt) {
    curr = curr || 0;
    cnt = cnt || 0;
    var index = input.indexOf(search);
    if (curr === nth) {
        if (~index) {
            return cnt;
        }
        else {
            return -1;
        }
    }
    else {
        if (~index) {
            return getPosition(input.slice(index + search.length),
              search,
              nth,
              ++curr,
              cnt + index + search.length);
        }
        else {
            return -1;
        }
    }
}
@RenanCoelho 波浪号 ( ~) 是 JavaScript 中的按位非运算符:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-24 09:07:13

这是我的解决方案,它只是遍历字符串直到n找到匹配项:

String.prototype.nthIndexOf = function(searchElement, n, fromElement) {
    n = n || 0;
    fromElement = fromElement || 0;
    while (n > 0) {
        fromElement = this.indexOf(searchElement, fromElement);
        if (fromElement < 0) {
            return -1;
        }
        --n;
        ++fromElement;
    }
    return fromElement - 1;
};

var string = "XYZ 123 ABC 456 ABC 789 ABC";
console.log(string.nthIndexOf('ABC', 2));

>> 16