在第n个字符处截取字符串

67
我想要做的是将字符串(例如"this.those.that")的第n个字符子串提取出来。比如说,从字符串开头到第二个.出现的位置应该返回"this.those"。同样的,从第二个.出现位置到字符串结尾应该返回"that"。抱歉如果我的问题表述不够清晰,很难解释。另外,请不要建议使用额外的变量,结果将以字符串形式而非数组形式返回,HTML标签需要保留。

1
将其拆分为数组,然后将数组的切片合并在一起有任何异议吗?它使用操作字符串或生成字符串的函数。 - tvanfosson
1
看起来你已经知道答案了;将字符串按照分隔符拆分,然后重新组合成一个新的字符串似乎是最好的选择。为什么要限制自己不使用数组呢? - Tejs
我表述不够清楚。我不想在字符串之外再创建一个额外的数组。使用字符串函数可以实现我想要达到的目的。我会修正问题的描述。 - Anonymous
@tvanfosson 我的答案为什么是错误的? - alex
@tvanfosson 我认为我们可能对OP的问题有不同的解释。 - alex
@alex - 我明白了。我把这个例子看作他感兴趣的特定n的实例。而你则将其视为针对任何给定的n产生结果,并选择了不同的n值。这似乎是合理的。我撤回我的反对意见并删除了我的评论。 - tvanfosson
5个回答

101

你可以不使用数组来完成它,但这需要更多的代码,并且可读性会降低。

通常情况下,你只需要使用足够的代码来完成工作,这样也可以增加可读性。如果你发现这个任务成为了一个性能问题(进行基准测试),那么你可以决定开始重构以提高性能。

var str = 'this.those.that',
    delimiter = '.',
    start = 1,
    tokens = str.split(delimiter).slice(start),
    result = tokens.join(delimiter); // those.that
    
console.log(result)

// To get the substring BEFORE the nth occurence
var tokens2 = str.split(delimiter).slice(0, start),
    result2 = tokens2.join(delimiter); // this

console.log(result2)

jsFiddle


4
我认为结果应该既是“this.those”,也是“that”? - tvanfosson
5
为了获得 "this.those" 和 "that",请将 slice(start) 改为 slice(0,start)。 - Dan Smart
@dan-smart 要获取 "this" 和 "those.that" 两部分,必须同时取这两个切片,请参见 下面链接 - hooke
2
通过在split中使用可选的limit参数,可以使代码更加简短:result = str.split(delimiter, start+1).join(delimiter)。 - Daniël Teunkens
@DaniëlTeunkens 看起来 limit 参数让你在匹配了一定数量的结果后停止分割,但在这种情况下它不起作用,因为我们需要类似于“负限制”的东西,即从右到左分割时停止。 - alex
显示剩余3条评论

12

试一下这个:

"qwe.fs.xczv.xcv.xcv.x".replace(/([^\.]*\.){3}/, '');
"xcv.xcv.x"

"qwe.fs.xczv.xcv.xcv.x".replace(/([^\.]*\.){**nth**}/, ''); - 这里的 nth 是要删除的出现次数。


这个答案比被接受的答案更好。有时分隔符可能是一个正则表达式(例如\s+)。在这种情况下,被接受的答案将不起作用。但这个答案会。 - killua8p
@killua8p 奇怪的推理。如果有时分隔符可能是正则表达式,那么你应该设计成这样。如果它是用于字符串分割的,你不应该总是偏爱正则表达式,因为你可能不需要它。YAGNI。 - alex
这个大约快了4倍。 - jazzgil

3

我很困惑为什么你想要纯粹使用字符串函数来完成任务,但我猜你可以像下面这样做:

//str       - the string
//c         - the character or string to search for
//n         - which occurrence
//fromStart - if true, go from beginning to the occurrence; else go from the occurrence to the end of the string
var cut = function (str, c, n, fromStart) {
    var strCopy = str.slice(); //make a copy of the string
    var index;
    while (n > 1) {
        index = strCopy.indexOf(c)
        strCopy = strCopy.substring(0, index)
        n--;
    }

    if (fromStart) {
        return str.substring(0, index);
    } else {
        return str.substring(index+1, str.length);
    }
}

然而,我强烈推荐像Alex的更简单的代码一样。

3

如果有人需要同时使用"this"和"those.that",并且按照Alex在他的评论所描述的方式,这里是修改过的代码:

var str = 'this.those.that',
    delimiter = '.',
    start = 1,
    tokens = str.split(delimiter),
      result = [tokens.slice(0, start), tokens.slice(start)].map(function(item) {
    return item.join(delimiter);
  }); // [ 'this', 'those.that' ] 

document.body.innerHTML = result;


1
如果你真的想坚持使用字符串方法,那么:
// Return a substring of s upto but not including
// the nth occurence of c
function getNth(s, c, n) {
  var idx;
  var i = 0;
  var newS = '';
  do {
    idx = s.indexOf(c);
    newS += s.substring(0, idx);
    s = s.substring(idx+1);
  } while (++i < n && (newS += c))
  return newS;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接