Javascript 仅在指定字符的第一个实例上拆分字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4607745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
split string only on first instance of specified character
提问by Ofeargall
In my code I split a string based on _
and grab the second item in the array.
在我的代码中,我拆分了一个字符串_
并抓取了数组中的第二个项目。
var element = $(this).attr('class');
var field = element.split('_')[1];
Takes good_luck
and provides me with luck
. Works great!
获取good_luck
并提供给我luck
。效果很好!
But, now I have a class that looks like good_luck_buddy
. How do I get my javascript to ignore the second _
and give me luck_buddy
?
但是,现在我有一个看起来像good_luck_buddy
. 如何让我的 javascript 忽略第二个_
并给我luck_buddy
?
I found this var field = element.split(new char [] {'_'}, 2);
in a c# stackoverflow answer but it doesn't work. I tried it over at jsFiddle...
我var field = element.split(new char [] {'_'}, 2);
在 ac# stackoverflow answer 中找到了这个,但它不起作用。我在 jsFiddle 上试过了...
回答by Mark
使用捕获括号:
"good_luck_buddy".split(/_(.+)/)[1]
"luck_buddy"
They are defined as
它们被定义为
If
separator
contains capturing parentheses, matched results are returned in the array.
如果
separator
包含捕获括号,则在数组中返回匹配的结果。
So in this case we want to split at _.+
(i.e. split separator being a sub string starting with _
) but alsolet the result contain some part of our separator (i.e. everythingafter _
).
因此,在这种情况下,我们希望拆分 at _.+
(即拆分分隔符是一个以 开头的子字符串_
),但也让结果包含我们的分隔符的某些部分(即之后的所有内容_
)。
In this example our separator (matching _(.+)
) is _luck_buddy
and the captured group (within the separator) is lucky_buddy
. Without the capturing parenthesis the luck_buddy
(matching .+
) would've not been included in the result array as it is the case with simple split
that separators are not included in the result.
在这个例子中,我们的分隔符(匹配_(.+)
)是_luck_buddy
,捕获的组(分隔符内)是lucky_buddy
。如果没有捕获括号,luck_buddy
(matching .+
) 将不会包含在结果数组中,因为简单的情况split
就是结果中不包含分隔符。
回答by kennebec
What do you need regular expressions and arrays for?
你需要正则表达式和数组做什么?
myString = myString.substring(myString.indexOf('_')+1)
var myString= "hello_there_how_are_you"
myString = myString.substring(myString.indexOf('_')+1)
console.log(myString)
回答by yonas
I avoid RegExp at all costs. Here is another thing you can do:
我不惜一切代价避免使用 RegExp。这是您可以做的另一件事:
"good_luck_buddy".split('_').slice(1).join('_')
回答by sebjwallace
Replace the first instance with a unique placeholder then split from there.
用唯一的占位符替换第一个实例,然后从那里拆分。
"good_luck_buddy".replace(/\_/,'&').split('&')
["good","luck_buddy"]
This is more useful when both sides of the split are needed.
当需要拆分的双方时,这更有用。
回答by Chandu
You can use the regular expression like:
您可以使用正则表达式,如:
var arr = element.split(/_(.*)/)
回答by Kraken
Nowadays String.prototype.split
does indeed allow you to limit the number of splits.
如今String.prototype.split
确实允许您限制拆分的数量。
str.split([separator[, limit]])
...
limit Optional
A non-negative integer limiting the number of splits. If provided, splits the string at each occurrence of the specified separator, but stops when limit entries have been placed in the array. Any leftover text is not included in the array at all.
The array may contain fewer entries than limit if the end of the string is reached before the limit is reached. If limit is 0, no splitting is performed.
str.split([separator[, limit]])
...
限制可选
限制拆分数量的非负整数。如果提供,则在每次出现指定分隔符时拆分字符串,但在数组中放置限制条目时停止。任何剩余的文本根本不包含在数组中。
如果在达到限制之前到达字符串的末尾,则数组包含的条目可能少于限制。如果 limit 为 0,则不执行拆分。
caveat
警告
It might not work the way you expect. I was hoping it would just ignore the rest of the delimiters, but instead, when it reaches the limit, it splits the remaining string again, omitting the part after the split from the return results.
它可能不会像您期望的那样工作。我希望它会忽略其余的分隔符,但是当它达到限制时,它会再次拆分剩余的字符串,从返回结果中省略拆分后的部分。
let str = 'A_B_C_D_E'
const limit_2 = str.split('_', 2)
limit_2
(2)?["A", "B"]
const limit_3 = str.split('_', 3)
limit_3
(3)?["A", "B", "C"]
I was hoping for:
我希望:
let str = 'A_B_C_D_E'
const limit_2 = str.split('_', 2)
limit_2
(2)?["A", "B_C_D_E"]
const limit_3 = str.split('_', 3)
limit_3
(3)?["A", "B", "C_D_E"]
回答by Alex Vidal
Javascript's String.split
unfortunately has no way of limiting the actual number of splits. It has a second argument that specifies how many of the actual split items are returned, which isn't useful in your case. The solution would be to split the string, shift the first item off, then rejoin the remaining items::
String.split
不幸的是,Javascript无法限制拆分的实际数量。它有第二个参数,用于指定返回的实际拆分项的数量,这在您的情况下没有用。解决方案是拆分字符串,将第一个项目移开,然后重新加入其余项目:
var element = $(this).attr('class');
var parts = element.split('_');
parts.shift(); // removes the first item from the array
var field = parts.join('_');
回答by Darren Lee
This solution worked for me
这个解决方案对我有用
var str = "good_luck_buddy";
var index = str.indexOf('_');
var arr = [str.slice(0, index), str.slice(index + 1)];
//arr[0] = "good"
//arr[1] = "luck_buddy"
OR
或者
var str = "good_luck_buddy";
var index = str.indexOf('_');
var [first, second] = [str.slice(0, index), str.slice(index + 1)];
//first = "good"
//second = "luck_buddy"
回答by ont.rif
With help of destructuring assignment it can be more readable:
在解构赋值的帮助下,它可以更具可读性:
let [first, ...rest] = "good_luck_buddy".split('_')
rest = rest.join('_')
回答by Chaim Leib Halbert
Fastest solution?
最快的解决方案?
I ran some benchmarks, and this solution won hugely:1
我运行了一些基准测试,这个解决方案大获全胜:1
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);
};
Performance comparison with other solutions
与其他解决方案的性能比较
The only close contender was the same line of code, except using substr
instead of slice
.
唯一的竞争者是同一行代码,除了使用substr
代替slice
.
Other solutions I tried involving split
or RegExp
s took a big performance hit and were about 2 orders of magnitudeslower. Using join
on the results of split
, of course, adds an additional performance penalty.
我尝试过的涉及split
or RegExp
s 的其他解决方案对性能造成了很大的影响,并且速度慢了大约 2个数量级。当然,join
在 的结果上使用split
会增加额外的性能损失。
Why are they slower? Any time a new object or array has to be created, JS has to request a chunk of memory from the OS. This process is very slow.
他们为什么慢?每当必须创建新对象或数组时,JS 都必须向操作系统请求一块内存。这个过程非常缓慢。
Here are some general guidelines, in case you are chasing benchmarks:
以下是一些通用指南,以防您追求基准:
- New dynamic memory allocations for objects
{}
or arrays[]
(like the one thatsplit
creates) will cost a lot in performance. RegExp
searches are more complicated and therefore slower than string searches.- If you already have an array, destructuring arrays is about as fast as explicitly indexing them, and looks awesome.
- 对象
{}
或数组的新动态内存分配[]
(如split
创建的)将在性能上花费很多。 RegExp
搜索更复杂,因此比字符串搜索更慢。- 如果你已经有一个数组,解构数组的速度和显式索引它们一样快,而且看起来很棒。
Removing beyond the first instance
超越一审
Here's a solution that will slice up to and including the nth instance. It's not quite as fast, but on the OP's question, gobble(element, '_', 1)
is still >2x faster than a RegExp
or split
solution and can do more:
这是一个解决方案,它将切片到并包括第 n 个实例。它不是那么快,但在 OP 的问题上,gobble(element, '_', 1)
仍然比 a RegExp
orsplit
解决方案快 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);
}
With the above definition, gobble('path/to/file.txt', '/')
would give the name of the file, and gobble('prefix_category_item', '_', 1)
would remove the prefix like the first solution in this answer.
使用上面的定义,gobble('path/to/file.txt', '/')
将给出文件的名称,并gobble('prefix_category_item', '_', 1)
像本答案中的第一个解决方案一样删除前缀。
- Tests were run in Chrome 70.0.3538.110 on macOSX 10.14.
- 测试在 macOSX 10.14 上的 Chrome 70.0.3538.110 中运行。