By Bobby Kumar


2008-11-11 11:15:32 8 Comments

How can I check if a string ends with a particular character in JavaScript?

Example: I have a string

var str = "mystring#";

I want to know if that string is ending with #. How can I check it?

  1. Is there a endsWith() method in JavaScript?

  2. One solution I have is take the length of the string and get the last character and check it.

Is this the best way or there is any other way?

30 comments

@Singh123 2018-06-20 04:43:07

This is the implementation of endsWith : String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

@Singh123 2018-06-20 04:37:51

This is the implementation of endsWith :

String.prototype.endsWith = function (str) { return this.length >= str.length && this.substr(this.length - str.length) == str; }

@Aniket Kulkarni 2014-03-05 14:57:39

From developer.mozilla.org String.prototype.endsWith()

Summary

The endsWith() method determines whether a string ends with the characters of another string, returning true or false as appropriate.

Syntax

str.endsWith(searchString [, position]);

Parameters

  • searchString : The characters to be searched for at the end of this string.

  • position : Search within this string as if this string were only this long; defaults to this string's actual length, clamped within the range established by this string's length.

Description

This method lets you determine whether or not a string ends with another string.

Examples

var str = "To be, or not to be, that is the question.";

alert( str.endsWith("question.") );  // true
alert( str.endsWith("to be") );      // false
alert( str.endsWith("to be", 19) );  // true

Specifications

ECMAScript Language Specification 6th Edition (ECMA-262)

Browser compatibility

Browser compatibility

@Vinicius 2015-05-08 16:30:19

Just another quick alternative that worked like a charm for me, using regex:

// Would be equivalent to:
// "Hello World!".endsWith("World!")
"Hello World!".match("World!$") != null

@chakrit 2010-03-30 19:40:46

UPDATE (Nov 24th, 2015):

This answer is originally posted in the year 2010 (SIX years back.) so please take note of these insightful comments:


ORIGINAL ANSWER:

I know this is a year old question... but I need this too and I need it to work cross-browser so... combining everyone's answer and comments and simplifying it a bit:

String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
  • Doesn't create a substring
  • Uses native indexOf function for fastest results
  • Skip unnecessary comparisons using the second parameter of indexOf to skip ahead
  • Works in Internet Explorer
  • NO Regex complications

Also, if you don't like stuffing things in native data structure's prototypes, here's a standalone version:

function endsWith(str, suffix) {
    return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

EDIT: As noted by @hamish in the comments, if you want to err on the safe side and check if an implementation has already been provided, you can just adds a typeof check like so:

if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

@Shauna 2013-09-11 21:18:45

Update for Googlers - Looks like ECMA6 adds this function. The MDN article also shows a polyfill. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

@lukas.pukenis 2013-09-26 07:33:16

What is my string contains multiple occurences of suffix?

@chakrit 2013-09-26 08:36:13

@lukas.pukenis it skips to the end and only check one instance of the suffix at the very end. it doesn't matter if the search string appears elsewhere.

@lukas.pukenis 2013-09-26 09:10:57

@chakrit thanks for clarification. Your code is really a beauty

@Mandeep 2014-02-27 08:08:44

Adding a check for the situation when the argument "suffix" is not defined": if (typeof String.prototype.endsWith !== 'function') { String.prototype.endsWith = function(suffix) { return this.indexOf(suffix, this.length - ((suffix && suffix.length) || 0)) !== -1; }; }

@IcedDante 2014-11-05 06:23:41

What are the regex complications you referred to?

@T.J. Crowder 2015-05-06 09:42:35

@AlexanderN: Of course, the endsWithSlow in that jsPerf does something different than the others: It's case-insensitive (and will fail if the value being checked has any characters with special meaning in regular expressions). Just the toLowerCase calls alone make it an invalid test relative to the others.

@T.J. Crowder 2015-05-06 10:04:45

Creating substrings isn't expensive on modern browsers; it may well have been in 2010 when this answer was posted. These days, the simple this.substr(-suffix.length) === suffix approach is fastest on Chrome, the same on IE11 as indexOf, and only 4% slower (fergetaboutit territory) on Firefox: jsperf.com/endswith-stackoverflow/14 And faster across the board when the result is false: jsperf.com/endswith-stackoverflow-when-false Of course, with ES6 adding endsWith, the point is moot. :-)

@chakrit 2015-11-24 02:37:14

@BenjaminDobell did you actually read the code? the second parameter makes the function skips ahead and only checks the only possible spot: length - suffix.length

@Benjamin Dobell 2015-11-25 03:34:53

@chakrit Well, yes, apparently not very thoroughly though. I apologise!

@chakrit 2015-11-25 04:29:39

@BenjaminDobell no worries : )

@Daniel T. 2016-01-28 14:57:36

The native endsWith() that got added with es2015 is also faster in Chrome than all the other methods. jsperf.com/endswith-stackoverflow/16

@Kevin Fegan 2016-09-30 19:39:00

@IcedDante - "What are the regex complications you referred to?" I would imagine the issue with RegEx is that care must be taken to insure that any "Special" characters in the search "Pattern" are properly escaped. This can be difficult if the "Pattern" is derived from arbitrary data, and especially so for someone not proficient in RegEx. But otherwise, a RegEx solution should work fine.

@Menth 2017-03-31 07:18:46

If you want to implement String.prototype.endsWith in case it doesn't exists you really need to make sure that it is compatible with native implementation! Here you are omitting optional "position" argument which may break any third party code! Please use polyfill profided by MDN.

@Mihail Malostanidis 2018-08-15 22:39:16

Shouldn't it just be ===0 and not !==-1, since that's the only position it can be in?

@Mihail Malostanidis 2018-08-15 22:40:20

Or how about !str.indexOf(...) :)

@João Haas 2019-12-03 15:57:05

If you're following the this.substr(-suffix.length) === suffix approach, you may use this.substr(-suffix.length, suffix.length) === suffix to get the behavior endswith('abc', '') = true

@faisalbhagat 2016-02-17 15:30:12

7 years old post, but I was not able to understand top few posts, because they are complex. So, I wrote my own solution:

function strEndsWith(str, endwith)
{
    var lastIndex = url.lastIndexOf(endsWith);
    var result = false;
    if (lastIndex > 0 && (lastIndex + "registerc".length) == url.length)
    {
        result = true;
    }
    return result;
}

@immazharkhan 2016-02-28 10:51:15

After all those long tally of answers, i found this piece of code simple and easy to understand!

function end(str, target) {
  return str.substr(-target.length) == target;
}

@Oskar Liljeblad 2009-09-27 08:34:28

Come on, this is the correct endsWith implementation:

String.prototype.endsWith = function (s) {
  return this.length >= s.length && this.substr(this.length - s.length) == s;
}

using lastIndexOf just creates unnecessary CPU loops if there is no match.

@BrainSlugs83 2011-09-20 22:52:33

Agreed. I really feel like this is the most performant solution offered as it has early aborts/sanity checking, it's short and concise, it's elegant (overloading the string prototype) and substring seems like much less of a resource hit than spinning up the regex engine.

@xmedeko 2011-10-12 12:23:14

Also like this solution. Just the function name is mispelled. Should be "endsWith".

@Brent Faust 2011-12-05 23:28:58

@BrainSlugs83 It's been a couple of years, but now this method is no faster than the 'indexOf' method mentioned above by chakrit, and under Safari, it is 30% slower! Here is a jsPerf test for the failure case over about a 50-character string: jsperf.com/endswithcomparison

@Timmmm 2014-11-10 14:25:55

Probably should use === though.

@Nikita Koksharov 2015-06-09 07:17:39

Didn't see apporach with slice method. So i'm just leave it here:

function endsWith(str, suffix) {
    return str.slice(-suffix.length) === suffix
}

@Erik K. 2015-11-10 14:45:18

You can simplify it a bit more: return str.slice(-1) === suffix;

@Jason Tu 2016-07-27 15:22:24

This is the best answer. Not sure why it doesn't have more upvotes.

@Dheeraj V.S. 2015-03-02 10:34:41

If you're using lodash:

_.endsWith('abc', 'c'); // true

If not using lodash, you can borrow from its source.

@ScrapCode 2015-04-30 06:56:04

Its been many years for this question. Let me add an important update for the users who wants to use the most voted chakrit's answer.

'endsWith' functions is already added to JavaScript as part of ECMAScript 6 (experimental technology)

Refer it here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith

Hence it is highly recommended to add check for the existence of native implementation as mentioned in the answer.

@rmehlinger 2015-02-04 20:25:20

@chakrit's accepted answer is a solid way to do it yourself. If, however, you're looking for a packaged solution, I recommend taking a look at underscore.string, as @mlunoe pointed out. Using underscore.string, the code would be:

function endsWithHash(str) {
  return _.str.endsWith(str, '#');
}

@Jon Skeet 2008-11-11 11:58:11

This version avoids creating a substring, and doesn't use regular expressions (some regex answers here will work; others are broken):

String.prototype.endsWith = function(str)
{
    var lastIndex = this.lastIndexOf(str);
    return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}

If performance is important to you, it would be worth testing whether lastIndexOf is actually faster than creating a substring or not. (It may well depend on the JS engine you're using...) It may well be faster in the matching case, and when the string is small - but when the string is huge it needs to look back through the whole thing even though we don't really care :(

For checking a single character, finding the length and then using charAt is probably the best way.

@ebruchez 2009-03-24 18:44:15

If this.lastIndexOf() returns -1, you can hit cases where it returns true dependong on this.length and str.length. Add a test that lastIndexOf() != -1.

@izb 2010-09-02 14:22:19

Why is the regex method broken?

@Jon Skeet 2010-09-02 14:37:44

@izb: The answers which are older than mine which try to use str+"$" as a regex are broken, as they may not be valid regexes.

@LahiruBandara 2014-11-18 09:04:44

So many things for such a small problem, just use this Regular Expression

var str = "mystring#";
var regex = /^.*#$/

if (regex.test(str)){
  //if it has a trailing '#'
}

@Quanlong 2014-10-23 09:40:10

For coffeescript

String::endsWith = (suffix) ->
  -1 != @indexOf suffix, @length - suffix.length

@Tabish Usman 2014-05-19 07:51:05

function strEndsWith(str,suffix) {
  var reguex= new RegExp(suffix+'$');

  if (str.match(reguex)!=null)
      return true;

  return false;
}

@brasofilo 2014-05-19 08:26:24

It's better if you explain why your code solves the problem. See the guide How to Answer.

@vlad_tepesch 2014-05-19 08:32:55

the suffix argument should be scanned for regex expressions that have to be escaped. using indexOf or lastIndexOf seems to be a better option.

@gtournie 2016-10-12 08:19:00

It won't work if the suffix contains any of these chars: .*+?^=!:${}()[]/\

@Ashley Davis 2014-04-29 10:20:02

I just learned about this string library:

http://stringjs.com/

Include the js file and then use the S variable like this:

S('hi there').endsWith('hi there')

It can also be used in NodeJS by installing it:

npm install string

Then requiring it as the S variable:

var S = require('string');

The web page also has links to alternate string libraries, if this one doesn't take your fancy.

@Bobby Kumar 2008-11-11 11:54:56

all of them are very useful examples. Adding String.prototype.endsWith = function(str) will help us to simply call the method to check if our string ends with it or not, well regexp will also do it.

I found a better solution than mine. Thanks every one.

@Daniel Nuriyev 2014-01-05 02:03:46

Do not use regular expressions. They are slow even in fast languages. Just write a function that checks the end of a string. This library has nice examples: groundjs/util.js. Be careful adding a function to String.prototype. This code has nice examples of how to do it: groundjs/prototype.js In general, this is a nice language-level library: groundjs You can also take a look at lodash

@termi 2013-07-11 13:40:16

if(typeof String.prototype.endsWith !== "function") {
    /**
     * String.prototype.endsWith
     * Check if given string locate at the end of current string
     * @param {string} substring substring to locate in the current string.
     * @param {number=} position end the endsWith check at that position
     * @return {boolean}
     *
     * @edition ECMA-262 6th Edition, 15.5.4.23
     */
    String.prototype.endsWith = function(substring, position) {
        substring = String(substring);

        var subLen = substring.length | 0;

        if( !subLen )return true;//Empty string

        var strLen = this.length;

        if( position === void 0 )position = strLen;
        else position = position | 0;

        if( position < 1 )return false;

        var fromIndex = (strLen < position ? strLen : position) - subLen;

        return (fromIndex >= 0 || subLen === -fromIndex)
            && (
                position === 0
                // if position not at the and of the string, we can optimise search substring
                //  by checking first symbol of substring exists in search position in current string
                || this.charCodeAt(fromIndex) === substring.charCodeAt(0)//fast false
            )
            && this.indexOf(substring, fromIndex) === fromIndex
        ;
    };
}

Benefits:

  • This version is not just re-using indexOf.
  • Greatest performance on long strings. Here is a speed test http://jsperf.com/starts-ends-with/4
  • Fully compatible with ecmascript specification. It passes the tests

@Matthew Brown 2013-06-15 06:33:56

This builds on @charkit's accepted answer allowing either an Array of strings, or string to passed in as an argument.

if (typeof String.prototype.endsWith === 'undefined') {
    String.prototype.endsWith = function(suffix) {
        if (typeof suffix === 'String') {
            return this.indexOf(suffix, this.length - suffix.length) !== -1;
        }else if(suffix instanceof Array){
            return _.find(suffix, function(value){
                console.log(value, (this.indexOf(value, this.length - value.length) !== -1));
                return this.indexOf(value, this.length - value.length) !== -1;
            }, this);
        }
    };
}

This requires underscorejs - but can probably be adjusted to remove the underscore dependency.

@mlunoe 2014-12-23 22:02:53

This is a bad solution, rather if you are already using underscore you should add this epeli.github.io/underscore.string to your dependencies and use their implementation: _.str.endsWith

@Tici 2013-05-02 08:01:18

I don't know about you, but:

var s = "mystring#";
s.length >= 1 && s[s.length - 1] == '#'; // will do the thing!

Why regular expressions? Why messing with the prototype? substr? c'mon...

@Martin Capodici 2015-04-06 22:47:03

'cus sometimes it's better when it's W.E.T.

@Mohammed Rafeeq 2012-10-17 10:55:25

String.prototype.endsWith = function(str) 
{return (this.match(str+"$")==str)}

String.prototype.startsWith = function(str) 
{return (this.match("^"+str)==str)}

I hope this helps

var myStr = “  Earth is a beautiful planet  ”;
var myStr2 = myStr.trim();  
//==“Earth is a beautiful planet”;

if (myStr2.startsWith(“Earth”)) // returns TRUE

if (myStr2.endsWith(“planet”)) // returns TRUE

if (myStr.startsWith(“Earth”)) 
// returns FALSE due to the leading spaces…

if (myStr.endsWith(“planet”)) 
// returns FALSE due to trailing spaces…

the traditional way

function strStartsWith(str, prefix) {
    return str.indexOf(prefix) === 0;
}

function strEndsWith(str, suffix) {
    return str.match(suffix+"$")==suffix;
}

@Juan Mendes 2013-04-23 15:41:35

You have to escape your string for regex escape sequences

@Daniel Nuriyev 2014-01-05 01:57:29

Regular expressions are slow even in fast languages. Just check the end of a string.

@Ebubekir Dirican 2012-06-22 15:06:02

String.prototype.endWith = function (a) {
    var isExp = a.constructor.name === "RegExp",
    val = this;
    if (isExp === false) {
        a = escape(a);
        val = escape(val);
    } else
        a = a.toString().replace(/(^\/)|(\/$)/g, "");
    return eval("/" + a + "$/.test(val)");
}

// example
var str = "Hello";
alert(str.endWith("lo"));
alert(str.endWith(/l(o|a)/));

@Dan Doyon 2011-07-18 21:46:08

A way to future proof and/or prevent overwriting of existing prototype would be test check to see if it has already been added to the String prototype. Here's my take on the non-regex highly rated version.

if (typeof String.endsWith !== 'function') {
    String.prototype.endsWith = function (suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
}

@XP1 2012-01-11 09:42:52

Using if (!String.prototype.hasOwnProperty("endsWith")) is the best way. With typeof, "MooTools and some of the other AJAX libraries will screw you up", according to "Crockford on JavaScript - Level 7: ECMAScript 5: The New Parts", at 15:50 min.

@user511941 2011-05-02 07:41:13

if you dont want to use lasIndexOf or substr then why not just look at the string in its natural state (ie. an array)

String.prototype.endsWith = function(suffix) {
    if (this[this.length - 1] == suffix) return true;
    return false;
}

or as a standalone function

function strEndsWith(str,suffix) {
    if (str[str.length - 1] == suffix) return true;
    return false;
}

@Mike Samuel 2009-03-24 20:32:36

/#$/.test(str)

will work on all browsers, doesn't require monkey patching String, and doesn't require scanning the entire string as lastIndexOf does when there is no match.

If you want to match a constant string that might contain regular expression special characters, such as '$', then you can use the following:

function makeSuffixRegExp(suffix, caseInsensitive) {
  return new RegExp(
      String(suffix).replace(/[$%()*+.?\[\\\]{|}]/g, "\\$&") + "$",
      caseInsensitive ? "i" : "");
}

and then you can use it like this

makeSuffixRegExp("a[complicated]*suffix*").test(str)

@Warren Blanchet 2009-05-21 22:50:13

This is nice and simple if you're checking for a constant substring.

@Tom Brito 2011-04-19 16:45:52

lastIndexOf scans all the string? I thought it would search from the end to the beggining.

@Tom Brito 2011-04-19 16:47:08

and what's the explanation? If I want to find the pattern "asdf" can I use /asdf$/.test(str)?

@Mike Samuel 2011-04-19 16:59:52

@TomBrito, lastIndexOf scans the entire string only if it finds no match, or finds a match at the beginning. If there is a match at the end then it does work proportional to the length of the suffix. Yes, /asdf$/.test(str) yields true when str ends with "asdf".

@Mike Samuel 2011-04-19 17:10:35

@TomBrito, edited to make it clear what lastIndexOf does. Thanks for pointing that out.

@Tom Brito 2011-04-20 13:44:44

Thanks, but I still don't understand what the slashes means in javascript. Does this have a name?

@Mike Samuel 2011-04-20 16:21:50

@Tom Brito, It's a regular expression literal. The syntax is borrowed from Perl. See developer.mozilla.org/en/Core_JavaScript_1.5_Guide/… or for an unnecessary level of detail, see section 7.8.5 of the EcmaScript language specification.

@BrainSlugs83 2011-09-20 22:45:17

@Mike Samuel: Good answer but I'm still left wondering if spinning up a new regex engine is really that more performant than a string scan, or if this were done properly, just calling substring (especially since your makeSuffixRegExp call is doing a very complicated replace which at the last is going to require a couple of full string scans and a bit of logic by the regex engine itself...)

@BrainSlugs83 2011-09-20 22:45:25

@Tom Brito: Regex is a really awesome tool to have in your tool belt, when you need it, just remember not all problems are nails. Regular-Expressions.info is a great place to learn more.

@Mike Samuel 2011-09-20 23:38:00

@BrainSlugs83, I agree re nails. Performance-wise, on some older interpreters, (assuming the regexp is cached) the test was a single call out to native code, while substring solutions tended to require multiple slow interpreter instructions and expensive object instantiations. That's no longer the case with modern interpreters. Obviously, the only way to tell is to benchmark.

@Adrien Be 2013-07-18 15:06:00

+1 for the cross-browser compatibility. Tested on Chrome 28.0.1500.72 m, Firefox 22.0, and IE9.

@Dan Abramov 2013-12-24 14:33:56

Cool, I didn't think of that. So simple & no monkey-patching. Thank you!

@Daniel Nuriyev 2014-01-05 01:56:22

Using a regular expression is slower than just checking the end of a string even in fast languages

@JayCrossler 2014-05-23 16:49:35

You can use something like: /kmz$/i.test(stringToTest) to test case-insensitively

@manish 2010-06-16 14:19:02

function check(str)
{
    var lastIndex = str.lastIndexOf('/');
    return (lastIndex != -1) && (lastIndex  == (str.length - 1));
}

@user73745 2009-03-04 15:58:04

return this.lastIndexOf(str) + str.length == this.length;

does not work in the case where original string length is one less than search string length and the search string is not found:

lastIndexOf returns -1, then you add search string length and you are left with the original string's length.

A possible fix is

return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length

@bobince 2009-03-04 16:08:15

You have earned the “Found a mistake in a Jon Skeet answer” badge. See your profile for details.

@duckyflip 2008-11-11 11:26:44

if( ("mystring#").substr(-1,1) == '#' )

-- Or --

if( ("mystring#").match(/#$/) )

Related Questions

Sponsored Content

93 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6249087 View
  • 7804 Score
  • 93 Answer
  • Tags:   javascript arrays

44 Answered Questions

[SOLVED] Sort array of objects by string property value

86 Answered Questions

[SOLVED] How do JavaScript closures work?

58 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

4 Answered Questions

76 Answered Questions

[SOLVED] How do I iterate over the words of a string?

  • 2008-10-25 08:58:21
  • Ashwin Nanjappa
  • 2150876 View
  • 2923 Score
  • 76 Answer
  • Tags:   c++ string split

31 Answered Questions

[SOLVED] startsWith() and endsWith() functions in PHP

  • 2009-05-07 12:14:27
  • Click Upvote
  • 813505 View
  • 1426 Score
  • 31 Answer
  • Tags:   php string

13 Answered Questions

[SOLVED] event.preventDefault() vs. return false

19 Answered Questions

[SOLVED] Is it possible to apply CSS to half of a character?

  • 2014-05-09 16:16:57
  • Mathew MacLean
  • 237541 View
  • 2746 Score
  • 19 Answer
  • Tags:   javascript html css

Sponsored Content