在我的代码中,我基于_分割字符串并获取数组中的第二项。

var element = $(this).attr('class');
var field = element.split('_')[1];

带来好运,给我带来好运。工作好了!

但是,现在我有了一个看起来像good_luck_buddy的类。我如何让我的javascript忽略第二个_,给我luck_buddy?

我找到了var field = element。Split (new char [] {'_'}, 2);在c# stackoverflow中回答,但它不起作用。我尝试在jsFiddle…


当前回答

Non-regex解决方案

我运行了一些基准测试,这个解决方案获得了巨大的成功

str.slice(str.indexOf(delim) + delim.length)

// as function
function gobbleStart(str, delim) {
    return str.slice(str.indexOf(delim) + delim.length);
}

// as polyfill
String.prototype.gobbleStart = function(delim) {
    return this.slice(this.indexOf(delim) + delim.length);
};

与其他解决方案的性能比较

唯一接近的竞争者是同一行代码,除了使用substr而不是slice。

我尝试的其他解决方案,包括拆分或regexp,性能受到了很大的影响,大约慢了2个数量级。当然,在拆分结果上使用join会增加额外的性能损失。

为什么它们变慢了?每当需要创建一个新对象或数组时,JS都必须向操作系统请求一大块内存。这个过程非常缓慢。

以下是一些通用指南,以防你在追逐基准测试:

为对象{}或数组[]分配新的动态内存(就像split所创建的那样)将在性能上付出很大的代价。 RegExp搜索更复杂,因此比字符串搜索慢。 如果你已经有一个数组,解构数组和显式索引数组一样快,而且看起来很棒。

从第一个实例移除

下面是一个解决方案,它将分割到并包括第n个实例。它没有那么快,但在OP的问题上,gobble(element, '_', 1)仍然比RegExp或split解决方案快>2倍,并且可以做更多:

/*
`gobble`, given a positive, non-zero `limit`, deletes
characters from the beginning of `haystack` until `needle` has
been encountered and deleted `limit` times or no more instances
of `needle` exist; then it returns what remains. If `limit` is
zero or negative, delete from the beginning only until `-(limit)`
occurrences or less of `needle` remain.
*/
function gobble(haystack, needle, limit = 0) {
  let remain = limit;
  if (limit <= 0) { // set remain to count of delim - num to leave
    let i = 0;
    while (i < haystack.length) {
      const found = haystack.indexOf(needle, i);
      if (found === -1) {
        break;
      }
      remain++;
      i = found + needle.length;
    }
  }

  let i = 0;
  while (remain > 0) {
    const found = haystack.indexOf(needle, i);
    if (found === -1) {
      break;
    }
    remain--;
    i = found + needle.length;
  }
  return haystack.slice(i);
}

根据上面的定义,gobble('path/to/file.txt', '/')将给出文件的名称,而gobble('prefix_category_item', '_', 1)将像这个答案中的第一个解决方案一样删除前缀。


测试在macOSX 10.14上的Chrome 70.0.3538.110中运行。

其他回答

这适用于我的Chrome + FF:

"foo=bar=beer".split(/^[^=]+=/)[1] // "bar=beer"
"foo==".split(/^[^=]+=/)[1] // "="
"foo=".split(/^[^=]+=/)[1] // ""
"foo".split(/^[^=]+=/)[1] // undefined

如果你也需要钥匙,试试这个:

"foo=bar=beer".split(/^([^=]+)=/) // Array [ "", "foo", "bar=beer" ]
"foo==".split(/^([^=]+)=/) // [ "", "foo", "=" ]
"foo=".split(/^([^=]+)=/) // [ "", "foo", "" ]
"foo".split(/^([^=]+)=/) // [ "foo" ]

//[0] = ignored (holds the string when there's no =, empty otherwise)
//[1] = hold the key (if any)
//[2] = hold the value (if any)

对于像我这样不习惯正则表达式的初学者来说,这个解决方案是有效的:

   var field = "Good_Luck_Buddy";
   var newString = field.slice( field.indexOf("_")+1 );

slice()方法提取字符串的一部分并返回一个新字符串,indexOf()方法返回字符串中指定值第一次出现的位置。

用唯一的占位符替换第一个实例,然后从那里拆分。

"good_luck_buddy".replace(/\_/,'&').split('&')

["good","luck_buddy"]

当拆分的双方都需要时,这更有用。

如果你正在寻找一种更现代的方式来做这件事:

let raw = "good_luck_buddy"

raw.split("_")
    .filter((part, index) => index !== 0)
    .join("_")

Mark F的解决方案很棒,但旧的浏览器不支持。Kennebec的解决方案很棒,老浏览器也支持,但不支持regex。

所以,如果你正在寻找一个解决方案,只分割你的字符串一次,这是由旧浏览器支持和支持regex,这是我的解决方案:

String.prototype.splitOnce = function(正则表达式) { Var match = this.match(正则表达式); 如果(匹配) { var match = this.indexOf(match[0]); [这返回。substring (0, match_i), 这一点。Substring (match_i + match[0].length)]; } 其他的 {返回[这个,""];} } Var STR = "某事/////另一件事///再次"; 警报(str.splitOnce (/ \ / + /) [1]);