JavaScript: Check if String Contains a Substring

A common operation in many programming languages is to check if a string contains another string. While it's a simple and common task, the method names often differ between programming languages. For example, here is a small sample of the methods used to achieve this in various languages:

  • Java: String.contains(), String.indexOf(), etc.
  • Python: in operator, String.index(), String.find()
  • Go: strings.Contains()
  • Ruby: string.include?

You get the point. There are a million ways to do this, and it seems like each language implements it differently.

Anyway, let's see a few of the ways in which you can check if string contains a substring in JavaScript.

Note: The first two methods shown below also works on arrays, which tells you if an array contains a given value (or the index of it for indexOf()). Keep this in mind when reading the article as it'll likely help you for similar use-cases.

The String.includes() Method

This method was introduced in ES6 and is typically the preferred method for simple use-cases. If all you need to do is get a boolean value indicating if the substring is in another string, then this is what you'll want to use.

It works like this:

> let str = 'stackabuse';
> let substr = 'stack';
> str.includes(substr);
true

As you can see, a boolean value is returned since the string "stack" is a substring of "stackabuse".

This is a case sensitive search, so the following will not match the substring:

> let str = 'StackAbuse';
> let substr = 'stack';
> str.includes(substr);
false

While this is enough for most use-cases, the includes() method also provides another option that may be useful to you. A second argument can be provided that tells the method at which index to start the search. So if you know that the substring isn't contained in the first 50 characters (or you just don't want it to match those characters), then you can use the method like this:

str.includes(substr, 50);

An offset of below 0 just starts the search from index 0, and an offset greater than string.length returns false since the search starts from string.length.

The String.indexOf() Method

The String.indexOf() method is much like the previous includes() method (and it's suitable to be used in a polyfill for includes() as well), but the only difference is the return value. Instead of returning a boolean value indicating the presence of the substring, it actually returns the index location of the substring, or -1 if it isn't present.

Here's an example:

> let str = 'stackabuse';
> let substr = 'abuse';
> str.indexOf(substr);
5
> str.indexOf('apple');
-1

As you can see, this method returns the 0-based index position of the substring, and a -1 when the substring wasn't found.

Just like the includes() method, the indexOf() method is case sensitive and also supports the offset parameter:

> let str = 'StackAbuse';
> let substr = 'abuse';
> str.indexOf(substr);
-1
> str.indexOf('Abu', 3);
5
> str.indexOf('Abu', 6);
-1

This method is useful for when you need to know the exact location of the substring, however, it's not as clean when simply using it as a boolean:

let str = 'stackabuse';
let substr = 'stack';

if (str.indexOf(substr) > -1) {
    console.log('Found the substring!');
}

In cases like this you should use the includes() method instead as it's more error-prone.

Regex

One of the more useful and powerful ways to check for a substring is to use regular expressions, or regex. Using regex for a task like this gives you a lot more flexibility than with the previous methods where you can only check for a constant string. While regex is too big of a subject to completely cover here, we can at least take a look at some of the useful features for our use-case.

Checking for substrings in a string with regex can be achieved using the RegExp.test() method:

> let str = 'stackabuse';
> /stack/.test(str);
true

Unlike the previous two methods, we can now do case insensitive searches with the i flag:

> let str = 'StackAbuse';
> /stack/i.test(str);
true

As a more complex example, let's say you want to see if a string contains a zip code (5 digit postal codes), but you don't really care what zip code is in the string. This kind of problem can't be solved using includes() or indexOf(). But with regex, we can easily test this:

> let str = 'My zip code is 90210';
> /\d{5}/.test(str);
true
> str = 'My address is 123 Fake St.';
> /\d{5}/.test(str);
false

While JavaScript isn't necessarily known for its speed anyway, keep in mind that this will be slower than a simpler method like includes(), so you should only use it for the more complex cases that can't be solved with a simpler solution.

Conclusion

Manipulating and inspecting strings is one of the most common tasks performed in many programming languages, especially with user-facing code. For many different reasons, like validating strings, you'll need to check if a string contains a substring. In this article we saw a few different methods provided by JavaScript that allows you to do exactly that.