1011

What is the difference between

alert("abc".substr(0,2));

and

alert("abc".substring(0,2));

They both seem to output “ab”.

Difference Engine
  • 12,025
  • 5
  • 21
  • 11
  • 20
    Note, `substring` outperforms all others on Chrome (according to the now-defunct jsperf.com) as of late. – Steven Lu Jul 16 '13 at 21:02
  • 5
    Adding on to @Derek comment... Unlike the `slice` method, `substring` does not handle the adjustment for negative parameters. – Dzeimsas Zvirblis Jun 27 '16 at 19:08
  • 5
    I think the more important question is "why does JavaScript have both a `substr` method and a `substring` method"? This is really the preferred method of overloading? – Sinjai Jan 26 '18 at 06:11
  • 11
    As of today, MDN has a big red warning about `substr()` being what you might call "pseudo-deprecated" at the top of the docs page here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr - Does anyone have more information about this, e.g. is there any browser that is planning to actually deprecate `substr()` at any point in the future? Or as Steven Lu suggested, might there be performance disadvantages to using `substr()` going forward? – Sideways S Sep 17 '18 at 17:16
  • @jamess As of today there's no warning. – codekandis Oct 24 '20 at 18:25
  • 2
    @codekandis it's at the bottom table: https://i.imgur.com/BHkYWHA.png – Paul Jan 08 '21 at 11:03
  • @Sinjai That is arguably the better question, particularly when you consider that many C-like scripting languages with a substring function accept length as a second-parameter including Perl and Awk and PHP. But for whatever reason EMCAScript standards decided to go the other direction, and deprecate the length-based substring function despite having widespread adoption. – Leslie Krause Nov 27 '22 at 21:22

11 Answers11

1093

The difference is in the second argument. The second argument to substring is the index to stop at (but not include), but the second argument to substr is the maximum length to return.

Links?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring

DecPK
  • 24,537
  • 6
  • 26
  • 42
Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
  • 77
    Sounds like a common source of error. Good to know the difference. Found additional comments about this here: http://rapd.wordpress.com/2007/07/12/javascript-substr-vs-substring/ – schnaader Sep 19 '10 at 11:46
  • 3
    @Pawel also when you want it to the end of the string (no second argument) – André Chalella Oct 20 '15 at 02:48
  • This is so ridiculous that I almost miss the days of developing Java applets. ('Almost', because we had to worry about IE back then.) – Michael Scheper Jul 19 '16 at 10:22
  • 5
    You should also mention the difference on the first argument, which can be negative for substr (in which case it starts from the end), but not for substring. See JefferMC answer, but it has so many less votes that a lot of people might miss this important part. – youen Jul 26 '17 at 19:46
  • 9
    As this is the by far most upvoted answer, it should probably be edited to include that `String.prototype.substr()` is deprecated... (It is defined in [Annex B](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-string.prototype.substr) of the ECMA-262 standard, whose [introduction](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers) states: "… Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. …") – T S Nov 01 '18 at 13:52
  • 5
    ```substr``` handle negative start value whereas ```substring``` doesn't: ```"Hello".substr(-2); // return "lo"``` ```"Hello".substring(-2); // return "Hello"``` – Florian Callewaert Jun 19 '19 at 07:45
  • Am I the only one who thinks the substring end parameter should point to the last character? The times I have chopped the last character off! – MortimerCat Feb 10 '21 at 10:32
406

substr (MDN) takes parameters as (from, length).
substring (MDN) takes parameters as (from, to).

Update: MDN considers substr legacy.

alert("abc".substr(1,2)); // returns "bc"
alert("abc".substring(1,2)); // returns "b"

You can remember substring (with an i) takes indices, as does yet another string extraction method, slice (with an i).

When starting from 0 you can use either method.

Hasan Sefa Ozalp
  • 6,353
  • 5
  • 34
  • 45
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
53

As hinted at in yatima2975's answer, there is an additional difference:

substr() accepts a negative starting position as an offset from the end of the string. substring() does not.

From MDN:

If start is negative, substr() uses it as a character index from the end of the string.

So to sum up the functional differences:

substring(begin-offset, end-offset-exclusive) where begin-offset is 0 or greater

substr(begin-offset, length) where begin-offset may also be negative

Cadoiz
  • 1,446
  • 21
  • 31
JefferMC
  • 686
  • 6
  • 14
34

The main difference is that

  • substr() allows you to specify the maximum length to return
  • substring() allows you to specify the indices and the second argument is NOT inclusive

There are some additional subtleties between substr() and substring() such as the handling of equal arguments and negative arguments. Also note substring() and slice() are similar but not always the same.

  //*** length vs indices:
    "string".substring(2,4);  // "ri"   (start, end) indices / second value is NOT inclusive
    "string".substr(2,4);     // "ring" (start, length) length is the maximum length to return
    "string".slice(2,4);      // "ri"   (start, end) indices / second value is NOT inclusive

  //*** watch out for substring swap:
    "string".substring(3,2);  // "r"    (swaps the larger and the smaller number)
    "string".substr(3,2);     // "in"
    "string".slice(3,2);      // ""     (just returns "")

  //*** negative second argument:
    "string".substring(2,-4); // "st"   (converts negative numbers to 0, then swaps first and second position)
    "string".substr(2,-4);    // ""
    "string".slice(2,-4);     // ""

  //*** negative first argument:
    "string".substring(-3);   // "string"        
    "string".substr(-3);      // "ing"  (read from end of string)
    "string".slice(-3);       // "ing"        
  
Cadoiz
  • 1,446
  • 21
  • 31
Nate Lipp
  • 700
  • 1
  • 7
  • 9
  • 3
    You missed the useful "negative second argument" for `slice`: `"string".slice(2,-2); // "ri"` – Paul May 31 '20 at 19:39
27

Another gotcha I recently came across is that in IE 8, "abcd".substr(-1) erroneously returns "abcd", whereas Firefox 3.6 returns "d" as it should. slice works correctly on both.

More on this topic can be found here.

yatima2975
  • 6,580
  • 21
  • 42
15

The big difference is, substr() is a deprecated method that can still be used, but should be used with caution because they are expected to be removed entirely sometime in the future. You should work to remove their use from your code. And the substring() method succeeded and specified the former one.

  • 2
    Can you point to a reliable source that indicates the deprecation of `substr()`? I have read it from several people, but I cannot find any information on the web that supports the statement. Plus, Mozilla does not include it on the list of deprecated/obsolete features: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features – DanielM Nov 08 '16 at 10:01
  • @DanielM As far as I remember, it was deprecated when I post this answer, maybe the article changed and it's now not deprecated *(but not sure)*.. But still recorded on some articles such as in http://sstut.com/javascript/substring-method.php as deprecated. – 5ervant - techintel.github.io Nov 08 '16 at 16:02
  • 4
    @DanielM `String.prototype.substr()` is defined in [Annex B](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-string.prototype.substr) of the ECMA-262 standard, whose [introduction](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-additional-ecmascript-features-for-web-browsers) states: "… Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. …" – T S Nov 01 '18 at 13:44
  • @TS `substr()` is really noted as deprecated on some documents. – 5ervant - techintel.github.io Nov 01 '18 at 17:52
  • Yes, that's what I said: It is noted as deprecated in the standard! Or don't you consider "should not use or assume the existence of these features" as deprecated? OK, they don't use the word "deprecated", but the description seems very clear to me... – T S Nov 01 '18 at 17:56
  • The Mozilla document you link to says while substr is not strictly deprecated it is considered a legacy function and should be avoided when possible. Worth mentioning so not sure why you were downvoted. – julian Jan 10 '19 at 02:57
  • @julian Because they can't see `substr()` on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features after this answer has been made. – 5ervant - techintel.github.io Jan 10 '19 at 05:04
  • 3
    This should be the an accepted answer as of today. Using legacy functions when there's alternative is not an option for good code. Please upvote this answer to make it more visible as Google leads to this page. – vbezhenar Mar 14 '19 at 09:33
  • Deprecitation is also notet here: https://medium.com/@gustavoalvescc/javascript-tips-slice-substr-substring-7fb052a45802#4177 – awe Jan 24 '22 at 11:55
  • @vbezhenar Is it really correct to say "there's alternative" when `substring()` is not even remotely comparable to `substr()` in usage? Usually when I want a substring, I know the desired length, so `substring()` incurs extraneous arithmetic. – Leslie Krause Nov 27 '22 at 21:02
9

The difference is second parameter. Their second parameters, while both numbers, are expecting two different things:

When using substring the second parameter is the first index not to include:

var s = "string";
s.substring(1, 3); // would return 'tr'

var s = "another example";
s.substring(3, 7); // would return 'ther'

When using substr the second parameter is the number of characters to include in the substring:

var s = "string";
s.substr(1, 3); // would return 'tri'

var s = "another example";
s.substr(3, 7); // would return 'ther ex'
Kmeixner
  • 1,664
  • 4
  • 22
  • 32
CurnalCurz
  • 91
  • 1
  • 2
6

substring(): It has 2 parameters "start" and "end".

  • start parameter is required and specifies the position where to start the extraction.
  • end parameter is optional and specifies the position where the extraction should end.

If the end parameter is not specified, all the characters from the start position till the end of the string are extracted.

var str = "Substring Example";
var result = str.substring(0, 10);
alert(result);

Output : Substring

If the value of start parameter is greater than the value of the end parameter, this method will swap the two arguments. This means start will be used as end and end will be used as start.

var str = "Substring Example";
var result = str.substring(10, 0);
alert(result);

Output : Substring

substr(): It has 2 parameters "start" and "count".

  • start parameter is required and specifies the position where to start the extraction.

  • count parameter is optional and specifies the number of characters to extract.

var str = "Substr Example";
var result = str.substr(0, 10);
alert(result);


Output : Substr Exa

If the count parameter is not specified, all the characters from the start position till the end of the string are extracted. If count is 0 or negative, an empty string is returned.

var str = "Substr Example";
var result = str.substr(11);
alert(result);

Output : ple
raju poloju
  • 119
  • 2
  • 2
3

substring(startIndex, endIndex(not included))

substr(startIndex, how many characters)

const string = 'JavaScript';

console.log('substring(1,2)', string.substring(1,2)); // a
console.log('substr(1,2)', string.substr(1,2)); // av
Sajith Mantharath
  • 2,297
  • 2
  • 17
  • 19
1
let str = "Hello World"

console.log(str.substring(1, 3))  // el -> Excludes the last index
console.log(str.substr(1, 3))  // ell -> Includes the last index
Gaurav
  • 857
  • 3
  • 21
  • 29
-3

EDIT: This answer is with reference to R programming

Here are major differences between substr() and substring():

  1. substr() has arguments start & stop while substring as arguments first & last.

    substr(x, start, stop)

and

substring(text, first, last = 1000000L)

EXAMPLE

substr("abcdef", start = 2, stop=4)
[1] "bcd"

substring("abcdef", first = 2, last = 4)    
[1] "bcd"
  1. substring function has a large default value [1000000L] of 'last' argument so you may skip specifying that while substr function needs you to specify the value of stop argument.

EXAMPLE

substr("abcdef", start = 2)
Error in substr("abcdef", start = 2) : 
  argument "stop" is missing, with no default

substring("abcdef", first = 2)
[1] "bcdef"
  1. If you apply substr function to several starting or stopping points, the function uses only the first entry (i.e. the stopping point 1) while substring function will extract several possible strings.

EXAMPLE

> substr('abcdef', 1:3, 5)
[1] "abcde"
> substr('abcdef', 1:3, 5:6)
[1] "abcde"
> substr('abcdef', 1, 5:6)
[1] "abcde"
> substring('abcdef', 1:3, 5)
[1] "abcde" "bcde"  "cde"  
> substring('abcdef', 1, 5:6)
[1] "abcde"  "abcdef"
> substring('abcdef', 1:3, 5:6)
[1] "abcde" "bcdef" "cde"  

Someone mention use of negative index/zero. Both are accepted by substr() and substring().

EXAMPLE

> substr('abcdef', -2, 3)
[1] "abc"
> substring('abcdef', -2, 3)
[1] "abc"
> substring('abcdef', 0, 3)
[1] "abc"
> substr('abcdef', 0, 3)
[1] "abc"

Important Note for using substr() or substring() for string replacement:

The replacement needs to have the same number of characters as the replaced part of your data. If you want to replace a substring with a string with different length, you might have a look at the gsub() function.

P.S. I am using R version 4.0.4

Dr Nisha Arora
  • 632
  • 1
  • 10
  • 23
  • This answer is **wrong** for **negative numbers**, as they are not treated the same. `substr(-2)` will start at position _-2 from the end_ of the string, returning the last two characters. `substring` converts _all negative numbers_ to zero or string lengths. So `substring(-2)` will be converted to `substring(0)` returning the whole string. MDN: [_Any argument value that is less than 0 or greater than stringName.length is treated as if it were 0 and stringName.length, respectively._](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) – Michel Jan 20 '22 at 07:04
  • @Michel. I didn't notice tag #javascript and answered for how it works in R BUT my note clearly mentions I am providing code & explanation for R. – Dr Nisha Arora Jan 21 '22 at 05:08