32

I am not very familiar with regex. I was trying to test if a string ends with another string. The code below returns null when I was expecting true. What's wrong with the code?

var id = "John";
var exists  ="blahJohn".match(/id$/);
alert(exists);

11 Answers 11

45

Well, with this approach, you would need to use the RegExp constructor, to build a regular expression using your id variable:

var id = "John";
var exists = new RegExp(id+"$").test("blahJohn");
alert(exists);

But there are plenty ways to achieve that, for example, you can take the last id.length characters of the string, and compare it with id:

var id = "John";
var exist = "blahJohn".slice(-id.length) == id; // true
Sign up to request clarification or add additional context in comments.

Comments

9

You would need to use a RegExp() object to do that, not a literal:

var id = "John",
    reg = new RegExp(id+"$");

alert( reg.test("blahJon") );

That is, if you do not know the value you are testing for ahead of runtime. Otherwise you could do:

alert( /John$/.test("blahJohn") );

1 Comment

Should be /John$/.test("blahJohn")
1

Try this -

var reg = "/" + id + "$/";
var exists  ="blahJohn".match(reg);

1 Comment

@Tony - Why doesn't this work? Can you explain please? I think this should work fine.
1

The nicer way to do this is to use RegExp.test:

(new RegExp(id + '$')).test('blahJohn'); // true
(new RegExp(id + '$')).test('blahJohnblah'); // false

Even nicer would be to build a simple function like this:

function strEndsWith (haystack, needle) {
    return needle === haystack.substr(0 - needle.length);
}

strEndsWith('blahJohn', id); // true
strEndsWith('blahJohnblah', id); // false

2 Comments

The substr method on IE < 9 is buggy, it cannot handle negative indices, e.g., testing: 'abc'.substr(-1) == 'c' fails, IE's substr returns the whole string. I would recommend the slice instead. Cheers.
@CMS Thanks. I won't change it, since your answer is accepted.
1
var id = new RegExp("John");
var exists  ="blahJohn".match(id);
alert(exists);

try this

Comments

1

I like @lonesomeday 's solution, but Im fan of extending the String.prototype in these scenarios. Here's my adaptation of his solution

String.prototype.endsWith = function (needle) {
     return needle === this.substr(0 - needle.length);
}

So can be checked with

if(myStr.endsWith("test")) // Do awesome things here. 

Tasty...

Comments

1
var id = "John";

(new RegExp(`${id}$`)).test('blahJohn');  // true
(new RegExp(`${id}$`)).test('blahJohna'); // false

`${id}$` is a JavaScript Template strings which will be compiled to 'John$'.

The $ after John in RegExp stands for end of string so the tested string must not have anything after id value (i.e. John) in order to pass the test.

new RegExp(`${id}$`) - will compile it to /John$/ (so if id shouldn't be dynamic you can use just /John$/ instead of new RegExp(`${id}$`) )

2 Comments

Thank you for this code snippet, which may provide some immediate help. A proper explanation would greatly improve its educational value by showing why this is a good solution to the problem, and would make it more useful to future readers with similar, but not identical, questions. Please edit your answer to add explanation, and give an indication of what limitations and assumptions apply.
@GrumpyCrouton Cool, done :). Hope the explanation I"ve added helps to understand the solution.
0

Why using RegExp? Its expensive.

function EndsWith( givenStr, subst )
{
var ln = givenStr.length;
var idx = ln-subst.length;
return ( giventStr.subst(idx)==subst );
}

Much easier and cost-effective, is it?

2 Comments

@StewieGriffin that's the whole point, your answer is incorrect
Why using RegExp? Its expensive. Um, maybe for all the benefits regexp brings. Your function doesn't work: EndsWith("Foobar Baz", /baz|test|\d\d-\d\d-202\d/i);
0

If you need it for replace function, consider this regExp:

var eventStr = "Hello% World%";

eventStr = eventStr.replace(/[\%]$/, "").replace(/^[\%]/, ""); // replace eds with, and also start with %.

//output: eventStr = "Hello% World";

Comments

0

2022, ECMA 11

Just created this helper function, I find it more useful and clean than modifying the regex and recreating one everytime.

/**
 * @param {string} str 
 * @param {RegExp} search 
 * @returns {boolean}
 */
function regexEndsWith (str, search, {caseSensitive = true} = {})
{
    var source = search.source
    if (!source.endsWith('$')) source = source + '$'
    var flags = search.flags
    if (!caseSensitive && !flags.includes('i')) flags += 'i'
    var reg = new RegExp(source, flags)
    return reg.test(str)
}

Use it this way:

regexEndsWith('can you Fi    nD me?', /fi.*nd me?/, {caseSensitive: false})

Comments

-1

Here is a string prototype function that utilizes regex. You can use it to check if any string object ends with a particular string value:

Prototype function:

String.prototype.endsWith = function (endString) {
    if(this && this.length) {
        result = new RegExp(endString + '$').test(this);
        return result;
    }
    return false;
} 

Example Usage:

var s1 = "My String";
s1.endsWith("ring"); // returns true;
s1.endsWith("deez"); //returns false;

1 Comment

You should explain why this answers the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.