String.slice和String.substring有什么区别?


832

有谁知道这两种方法之间的区别?

String.prototype.slice
String.prototype.substring

215
这是JavaScript设计欠佳的一个示例,我们最终得到了三种方法都可以完成相同的工作,但又有不同的怪癖。IMO slice是行为异常最少的一种。
bobince 2010年

2
一眼就可以理解,IMO子字符串用于从idx到结尾取一个子字符串。尤其是对于菜鸟来说
mplungjan

1
根据此网站slice实际上可以替换substring并且没有理由使用它。
德里克·朕会功夫2012年

5
@AmolMKulkarni完全不正确。如果尝试var a = "asdf".substring(-1);,则将其视为var a = "asdf".substring(0);。没有异常抛出。而且,如果您使用var a = "asdf".substring(2, -1);,它会0代替-1(像之前一样)使用,并交换参数,使其表现为var a = "asdf".substring(0, 2);。我什至在IE 8上尝试了这些程序,结果无一例外
Ian

35
“我什至在IE 8上都尝试过这些”-我喜欢编程。
2015年

Answers:


858

slice()就像substring()有几种不同的行为一样。

Syntax: string.slice(start, stop);
Syntax: string.substring(start, stop);

他们有什么共同点:

  1. 如果start等于stop:返回一个空字符串
  2. 如果stop省略,则将字符提取到字符串的末尾
  3. 如果任一参数大于字符串的长度,则将使用字符串的长度来代替。

的区别 substring()

  1. 如果为start > stopsubstring则将交换这两个参数。
  2. 如果任一参数为负或为NaN,则将其视为0

的区别 slice()

  1. 如果为start > stopslice()则返回空字符串。(""
  2. 如果start为负:像substr()在Firefox中一样,从字符串末尾设置char 。在Firefox和IE中都观察到此行为。
  3. 如果stop为负:停止点设置为:(string.length – Math.abs(stop)原始值),但ECMA规范中Math.max(0, string.length + stop)所涵盖的边界为0(因此)除外。

来源:编程和开发的基本艺术:Javascript:substr()vs substring()


8
在您的上一个注释中slice(),应该是string.length - stop
Andy

16
在您关于的最后一个注释中slice(),我认为应该是,(string.length – 1) + stop或者要明确表明它是负面的,(string.length – 1) – Math.abs(stop)
Oriol 2012年

9
@Longpoke:String.slice已添加,因此存在与一致的字符串方法Array.slicesubstring一直在那里,所以他们没有打破它,而是添加了另一种方法。1.一致性很好,并且2.它使CoffeeScript的切片语法可以在数组和字符串上工作,所以这并不是一个糟糕的决定。@Oriol:在编辑它。
飞羊

6
在Firefox 22中,子字符串和slice之间似乎存在性能差异。jsperf.com/string
Rick

4
安迪是对的。stop将设置为string.length + stopif是否stop为负。请记住stop,提取的最后一个字符之后是索引!
user1537366 2014年

97

注意:如果您急于和/或正在寻找简短的答案,请滚动到答案的底部,然后阅读最后两行。如果不急,请阅读整本书。


让我首先说明事实:

语法:
string.slice(start,end)
string.substr(start,length)
string.substring(start,end)
注意#1:slice()==substring()

它能做什么?
slice()方法提取字符串的一部分,然后以新字符串返回提取的部分。
substr()方法提取从指定位置的字符开始的字符串部分,并返回指定数量的字符。
substring()方法提取字符串的一部分,然后以新字符串返回提取的部分。
笔记2:slice()==substring()

更改原始字符串?
slice()
substr()
substring()
注3:slice()==substring()

使用负数作为参数:
slice()选择从字符串末尾开始的字符
substr()选择从字符串末尾开始的字符
substring()不执行
注释#3:slice()==substr()

如果第一个参数大于第二:
slice()不执行
substr(),因为第二个参数不是一个位置,但长度值,它会像往常一样执行,没有任何问题
substring()将交换两个参数,并执行像往常一样

第一个参数:
slice()必需,指示:
substr()必需的起始索引,指示:
substring()必需的起始索引,指示:起始索引
注释4:slice()==substr()==substring()

第二个参数:
slice()可选,提取终止的位置(最多但不包括)
substr()可选,要提取的字符数可选,终止提取
substring()的位置(最多但不包括)
注解#5:slice()==substring()

如果忽略第二个参数怎么办?
slice()选择从字符串的开始位置到字符串末尾的
substr()所有字符选择从字符串的开始位置到字符串末尾的
substring()所有字符选择从字符串的开始位置到字符串末尾的所有字符
注意#6:slice()==substr()==substring()

因此,您可以说slice()和之间有区别substr(),而substring()基本上是的副本slice()

总结:
如果您知道将要停止的索引(位置)(但不包括在内),slice()
则如果知道要提取的字符的长度,请使用substr()



24

Ben Nadel撰写了一篇很好的文章,指出了这些函数的参数差异:

String.slice( begin [, end ] )
String.substring( from [, to ] )
String.substr( start [, length ] )

他还指出,如果slice的参数为负,则它们将从结尾引用字符串。Substring和substr不会。

是他关于此的文章。


3
这是不正确的,substr确实处理负参数。 '0123456789'.substr(-3, 2) -> '78'
尼尔·弗雷泽

14

一个答案很好,但是需要一点阅读。尤其是用新术语“停止”。

我的围棋(Go)–除上面丹尼尔(Daniel)的第一个回答外,还通过差异进行整理,使其变得有用:

1)负指标。子字符串需要正索引,并将负索引设置为0。slice的负索引表示从字符串末尾开始的位置。

"1234".substring(-2, -1) == "1234".substring(0,0) == ""
"1234".slice(-2, -1) == "1234".slice(2, 3) == "3"

2)交换索引。子字符串将对索引重新排序,以使第一个索引小于或等于第二个索引。

"1234".substring(3,2) == "1234".substring(2,3) == "3"
"1234".slice(3,2) == ""

--------------------------

一般评论-我觉得第二个索引是切片或子字符串的最后一个字符之后的位置很奇怪。我希望“ 1234” .slice(2,2)返回“ 3”。这使Andy的困惑超出了合理范围-我希望“ 1234” .slice(2,-1)返回“ 34”。是的,这意味着我是Java的新手。这也意味着这种行为:

"1234".slice(-2, -2) == "", "1234".slice(-2, -1) == "3", "1234".slice(-2, -0) == "" <-- you have to use length or omit the argument to get the 4.
"1234".slice(3, -2) == "", "1234".slice(3, -1) == "", "1234".slice(3, -0) == "" <-- same issue, but seems weirder.

我的2c。


11

子字符串和切片之间的区别是它们如何与否定的和可忽略的国外参数一起使用:

子字符串(开始,结束)

负参数将被解释为零。太大的值将被截断为字符串的长度:alert(“ testme” .substring(-2)); //“ testme”,-2变为0

此外,如果start> end,则参数会互换,即在起点和终点之间返回绘图线:

alert ( "testme" .substring (4, -1)); // "test"
// -1 Becomes 0 -> got substring (4, 0)
// 4> 0, so that the arguments are swapped -> substring (0, 4) = "test"

切片

从行尾开始测量负值:

alert ( "testme" .slice (-2)); // "me", from the end position 2
alert ( "testme" .slice (1, -1)); // "estm", from the first position to the one at the end.

它比奇怪的逻辑子字符串方便得多。

除IE8-以外的所有浏览器都支持substr的第一个参数的负值。

如果在大多数情况下使用这三种方法中的一种,它将是slice:否定参数,并且它保持和操作最明显。


4

substr:它使我们能够根据指定的索引来获取部分字符串。substr-string.substr(start,end)start的语法-开始索引告诉获取的开始位置。end-end索引告诉字符串从何处获取。它是可选的。

slice:它提供了根据指定的索引获取部分字符串的功能。它允许我们指定正数和索引。slice的语法-string.slice(start,end)start-起始索引告诉获取开始的位置,结束-end索引告诉到字符串获取的位置。它是可选的。在“拼接”中,开始索引和结束索引都有助于获取正负索引。

字符串中“ slice”的示例代码

var str="Javascript";
console.log(str.slice(-5,-1));

output: crip

字符串中“ substring”的示例代码

var str="Javascript";
console.log(str.substring(1,5));

output: avas

[*注:负索引从字符串的末尾开始。]


3

slice和substring方法之间的唯一区别是参数

两者都有两个参数,例如开始/起始和结束/至。

您不能将负值作为子字符串方法的第一个参数传递,而让slice方法从末尾遍历它。

切片方法参数详细信息:

REF:http : //www.thesstech.com/javascript/string_slice_method

争论

start_index 切片应从何处开始的索引。如果提供负值,则表示从最后开始。例如,最后一个字符为-1。 end_index 切片结束后的索引。如果未提供,则切片将从start_index到字符串的结尾。在负值的情况下,将从字符串末尾开始测量索引。

子字符串方法参数详细信息:

REF:http : //www.thesstech.com/javascript/string_substring_method

争论

from 应该是一个非负整数,用于指定子字符串应从何处开始的索引。 一个可选的非负整数,以提供在完成子字符串之前的索引。


0

对于slice(start, stop),如果stop为负,stop则将设置为:

string.length  Math.abs(stop)

而不是:

string.length  1  Math.abs(stop)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.