How to check whether a string contains a substring in JavaScript?

One of the most common things you have to do in programming is string comparison which is useful for searching and retrieving related data. You can do this with the following code

const mainString = "Hello world";
const substring = "world";
console.log(mainString.includes(substring)); // true

This solution uses the “includes” method to check if the subString is contained by the mainString. A problem arises however due to this comparison being case sensitive. This means that if you searched for the word, ‘World’ the comparison would rightfully fail. There are some cases however where we do want matches based on case insensitivity. For instance, you may be searching for the name of a person or location where it doesn’t matter whether both words are written in the same case. A search for ‘Lake placid‘ for example should match a search for ‘Lake Placid‘. Similarly we also want results for ‘lake placid‘. To properly compare these words we will cast each string to lowercase first before making the comparison.

const mainString = "Hello, World!";
const substring = "world";
const containsSubstring = mainString.toLowerCase().includes(substring.toLowerCase());
console.log(containsSubstring);  // true

This revised code will now match regardless of case because both mainString and subString are set to lowercase before any comparison is run. They will return a boolean of true or false depending on the input strings. Now, this code is fine but it will also only run on browsers that support ECMAScript 6. While this is over 94% of browsers, if you have to support legacy browsers, you’ll need to instead use a different approach as older browsers do not support the “includes” method. One way of doing this is using the “indexOf” method which returns -1 when a substring cannot be found

var mainString = "Hello, World";
var substring = "world";
console.log(mainString.toLowerCase().indexOf(substring.toLowerCase()) !== -1); // true

With this revision, we now have support for older browsers like Internet Explorer for environments where we still need to maintain backward compatibility. An alternative way of doing this is to use regular expressions.

var mainString = "Hello, World!";
var substring = "world";
var regex = new RegExp(substring, "i");
var containsSubstring = regex.test(mainString);
console.log(containsSubstring);  // true

We use the “i” flag as the second argument which will make the regular expression case-insensitive. Then we can use the test() method of the regular expression to check whether mainString contains the substring.

I should note that while regular expressions are more powerful and flexible, they can be slower overall compared to a direct method call.
Creating a regular expression object involves additional steps and can be overkill for a simple substring check.

Using a Real World Example

Now that we have several examples to choose from, here’s a real world example of how a search like this could be used. Supposing we have an html table with the following data:

<input type="text" id="searchInput" placeholder="Enter search text" onkeyup="filterTable()">
  <table id="data">
    <thead>
      <tr>
        <th>Animal Name</th>
        <th>Genus</th>
        <th>Epithet</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Human</td>
        <td>Homo</td>
        <td>Sapien</td>
      </tr>
      <tr>
        <td>Wolf</td>
        <td>Canis</td>
        <td>Lupus</td>
      </tr>
      <tr>
        <td>Lion</td>
        <td>Panthera</td>
        <td>Leo</td>
      </tr>
      
    </tbody>
  </table>

We would like to search on this table by the Animal Name, Genus or Epithet. So we create an input field that will allow us to type in our search term. On key up we filter the table results so that any row where any one of the columns matches will remain while any rows that do not match are hidden. To do so, we loop through the table rows and use the “toLowerCase()” and “includes” method to check if any of the columns contain the term we are looking for. Our search term is also set to lower case before any comparison is done Our JavaScript will then look something like this:

<script>
    function filterTable() {
      var input = document.getElementById("searchInput").value.toLowerCase();
      var table = document.getElementById("data");
      var rows = table.getElementsByTagName("tr");
      for (var i = 0; i < rows.length; i++) {
        var cells = rows[i].getElementsByTagName("td");
        var rowVisible = false;
        for (var j = 0; j < cells.length; j++) {
          var cellText = cells[j].textContent || cells[j].innerText;
          if (cellText.toLowerCase().includes(input)) {
            rowVisible = true;
            break;
          }
        }
        rows[i].style.display = rowVisible ? "" : "none";
      }
    }
  </script>

And that’s all there is to it. We can technically swap in any of the methods we use to determine a match based on whether we wanted to match using case sensitivity or case insensitivity for returning a matching result. Have fun experimenting and fine tuning the script to get the results to your own preferences or use cases.



1 Comment

  • Sam

    I appreciate the HTML table example along with the JavaScript code. Helped me understand how to implement the substring matching functionality and apply it to my own project.

Leave a Reply