How To Check If A String Contains Another Substring In JavaScript?

An overview of different ways to check if a string contains a given substring in JavaScript

  • By Daniyal Hamid
  • June 22, 2018
  • Comments
In This Article

Using indexOf()

This is perhaps the most commonly used way of testing for the presence of a substring within a given string. While it does the job well, you must note that the function is actually intended to return the index at which a given substring is found, and -1 when there's no match.

Return Value:

If match is found, position of the first occurrence in the string is returned.

If match is NOT found, -1 is returned.

Syntax:

str.indexOf(searchStr);
Variable Description
str The string to search within.
searchStr The string to search for.

Examples:

var str = 'Hello World!';

str.indexOf('hello'); // output: -1

str.indexOf('Hello'); // output: 0

str.indexOf('!'); // output: 11

From the results above, you may have noticed that indexOf results are case-sensitive.

Tips & Tricks:

Case Insensitive Search:

We can convert the string to lowercase temporarily and run indexOf on it, making it a case insensitive search. Consider the example below:

var str = 'Hello World!';
str.toLowerCase().indexOf('hello'); // output: 0

Please note that while this works, it may not be the ideal solution, you can use search() function (which is almost identical to indexOf).

Shorthand:

Using the bitwise negation operator ~ (which inverts the binary digits of an operand), the following:

'string'.indexOf('a') === -1; // output: true
Can be rewritten as:
~'string'.indexOf('a'); // output: 0 (which is a falsy value)

Here, the bitwise negation operator ~ is used to convert -1 into 0 (which is a falsy value), whereby all other non-zero values will be truthy. We can take this a step further and cast the result to boolean by using double negation operator like so:

!!~'string'.indexOf('a'); // output: false (boolean)

// or we could simply do this…
'string'.indexOf('a') > -1; // output: false (boolean)

Using search()

search() and indexOf() are very similar in terms of return value and functionality with the exception that the former accepts strings as well as regular expressions as input.

Return Value:

If match is found, position of the first occurrence in the string is returned.

If match is NOT found, -1 is returned.

Syntax:

str.search(regexp);
Variable Description
str The string to search within.
regexp

Can be any of the following:

  • A regular expression in literal notation (i.e. enclosed between slashes).
  • A regular expression object constructed by calling the constructor function of the RegExp object.
  • If a string is specified (enclosed within quotes), it's implictly converted to a regular expression using new RegExp(regexp).

Examples:

var str = 'Hello World!';

// method 1: string input
str.search('hello'); // output: -1

// method 2: regular expression literal notation (enclosed between slashes)
str.search(/Hello/); // output: 0

// method 3: calling the constructor function of the RegExp object
str.search(new RegExp('!')); // output: 11

From the results above, you may have noticed that search() results are case-sensitive.

Tips & Tricks:

Case Insensitive Search:

We can simply use the regular expression i flag to do a case-insensitive search. Consider the example below:

// method 1: regular expression literal notation
'Hello World!'.search(/hello/i); // output: 0

// method 2: using the RegExp object
'Hello World!'.search(new RegExp('hello', 'i')); // output: 0
Shorthand:

Similar to indexOf() shorthand, we can use the bitwise negation operator ~ (which inverts the binary digits of an operand) with search() as well. Consider the following:

'string'.search('a') === -1; // output: true
Which can be rewritten as:
~'string'.search('a'); // output: 0 (which is a falsy value)

Here, the bitwise negation operator ~ is used to convert -1 into 0 (which is a falsy value), whereby all other non-zero values will be truthy. We can take this a step further and cast the result to boolean by using double negation operator like so:

!!~'string'.search('a'); // output: false (boolean)

// or we could simply do this…
'string'.search('a') > -1; // output: false (boolean)

Using test()

The test() function accepts regular expressions which is similar to the search() function. The difference between the two is that test() returns a boolean value while search() returns the numeric index/position in a string.

Return Value:

If match is found, boolean true is returned.

If match is NOT found, boolean false is returned.

Syntax:

regexp.test(str);
Variable Description
regexp

The regular expression to match. Can be in either of the following two formats:

  1. Literal notation (i.e. enclosed between slashes).
  2. Regular expression object constructed by calling the constructor function of the RegExp object.
str The string to test regular expression against.

Example:

var str = 'Hello World!';

// method 1: regular expression literal notation (enclosed between slashes)
/hello/.test(str); // output: false (boolean)

// method 2: calling the constructor function of the RegExp object
(new RegExp('Hello')).test(str); // output: true (boolean)

You can perform a case-insensitive search by specifying the regular expressions i flag; /hello/i (literal notation) and new RegExp('hello', 'i') (RegExp object).

Using match()

For the sake of completeness, it's worth mentioning the match() method which accepts regular expressions that a string is matched against. This differs from test() and search() in terms of the return value; match() returns array of matches (more below). test() and search() are recommended if you just wish to know if a string matches a regular expression.

Return Value:

If match is found, array is returned that contains the entire matched string as the first element, followed by any results captured in regular expression parentheses (capture groups).

If match is NOT found, null is returned.

Syntax:

str.match(regexp);
Variable Description
str The string to find matches in.
regexp

The regular expression to match. Can be in either of the following two formats:

  1. Literal notation (i.e. enclosed between slashes).
  2. Regular expression object constructed by calling the constructor function of the RegExp object.

Determining Whether You Need match() Or Not:

  • For finding whether a string matches a regular expression or not, use test() or search();
  • If you only want the first match found, use exec() instead;
  • if you want to get capture groups and the global flag is set, use exec() instead.

Example:

var str = 'Hello World!';

// method 1: regular expression literal notation (enclosed between slashes)
str.match(/Hello/); // output: Array(1) ["Hello"]

// method 2: calling the constructor function of the RegExp object
str.test(new RegExp('Hello')); // output: Array(1) ["Hello"]

You can perform a case-insensitive search by specifying the regular expressions i flag; /hello/i (literal notation) and new RegExp('hello', 'i') (RegExp object).

This, of course, does not cover all the features of match() as we're only concerned with finding out whether a string contains another substring. You can read up more about this if you feel the need.

Tips & Tricks:

Returning Boolean Result:

Although not recommended if you wish to use this method solely to test whether the string contains another substring (use test() or search() instead), still obtaining a boolean result from a match could be useful in certain scenarios (especially where we're already using the matches later in our code). Returning a boolean result for match() is rather straightforward as the method returns null on failure (a falsy value) and an array on success (a truthy value), using this information we could simply use double negation (!!) on the result to cast it to boolean, for example:

var str = 'Hello World!';

!!str.match(/hello/i); // output: true

!!str.match(/foobar/i); // output: false

Using includes()

This method was introduced in EcmaScript 6 specification, therefore, support might not be great across different browsers (especially the old ones), so use with caution.

Return Value:

If match is found, boolean true is returned.

If match is NOT found, boolean false is returned.

Syntax:

str.includes(searchStr[, pos]);
Variable Description
str The string to search within.
searchStr The string to search for.
pos (optional - defaults to 0) The position in the string to start searching for searchStr.

Examples:

var str = 'Hello World!';

str.includes('World'); // output: true (boolean)

str.includes('world'); // output: false (boolean)

str.includes('Hello', 1); // output: false (boolean)

includes() function is case-sensitive.

Polyfill:

For cross-browser compatibility, you can use the following polyfill (via MDN):

if(!String.prototype.includes) {
    String.prototype.includes = function(search, start) {
        'use strict';
        
        if(typeof start !== 'number') {
            start = 0;
        }
        
        return (start+search.length <= this.length && this.indexOf(search, start) !== -1);
    };
}

Hope you found the information in this article useful. If there's something you'd like to add, let us know in the comments below!