Finding a match for a string within a text is a common task for developers. In this lesson you'll not only discover how to efficiently find substrings within a string but also delve into using regular expressions for finding strings.
By the end of this lesson, you'll have a firm grasp on leveraging these methods. Whether you're validating user input, or searching through massive texts, the skills you acquire here will be indispensable in your coding toolkit.
If you're looking for ways to replace strings, however, check out the next lesson. That said, a lot of the techniques shown in this lesson will probably be just as useful to you.
How to Match a String in JavaScript
There are many methods to match strings in JavaScript, which one you use depends on the specific task at hand. Here are the methods that you'll cover in this lesson:
All of these methods are string methods. That is, they are part of the String.prototype object which all strings have access to. This means that on any string, you can call these methods on them directly, or when accessed through a variable, array indexing, or object referencing.
There is some overlap between these methods. When deciding which one to use, try to use the one that best describes the task you are doing. Or the one whose scope more closely matches your task. For instance, if all you want to do is to check if a string contains another substring, then you'll want to use the method in the next section.
Check if a String Exists Within a String with .includes()
Sometimes all you are interested in is whether a string exists in another string. If so, then the .includes() method is for you. That method returns a boolean indicating whether a substring is present within a string. Here's an example:
let textToSearch = "Hello world!";
textToSearch.includes("world"); // true
textToSearch.includes("nomad"); // false
As you can see, if all you need to find is whether the target string is present, then .includes() is the method to use.
Get the Position of a String Within a String with .indexOf() and .lastIndexOf()
The .indexOf() method returns the index of the first occurrence of a substring within a string. If the substring is not found, it returns -1. A similar method is .lastIndexOf() which returns the index of the last occurrence of a substring within a string. If the substring is not found, then it returns -1. Here's an example:
let textToSearch = "Hello world world";
// The substring "world" is found at index 6, at the `w`
textToSearch.indexOf("world"); // 6
// The last substring "world" is found at index 12, at the `w`
textToSearch.lastIndexOf("world"); // 12
// If the substring is not found, it returns -1
textToSearch.indexOf("nomad"); // -1
// You can call string methods directly on the string too:
"Hello world".indexOf("world"); // 6
As you can see, if all you need to find is where the target string starts, then .indexOf() or .lastIndexOf() is the method to use.
Using .startsWith() and .endsWith()
Sometimes all you are interested in is whether a string starts or ends with another string. If so, then the .startsWith() or .endsWith() methods are for you. These method returns a boolean indicating whether a string starts or ends with a substring. Here's an example:
let textToSearch = "Hello world!";
// Starts with
textToSearch.startsWith("Hello"); // true
textToSearch.startsWith("!"); // false
// Ends with
textToSearch.endsWith("!"); // true
textToSearch.endsWith("Hello"); // false
Use Regex to Find Strings Within Strings
Sometimes a regular string won't do, and you'll need to use a regular expression to find a match. Regular expressions are a powerful tool for matching patterns in text. They are a language unto themselves, so details of regex won't be covered in this lesson. However, here you'll learn how to use some pre given examples of regex to find matches in strings.
Why might you need regular expressions? Well, let's say you want to find all the words that start with a capital letter in a text. You could write a function that loops through the text and checks each word, but that would be a lot of work.
Instead, you can use a regular expression to find all the words that start with a capital letter. Or words that contain a number. Or words that contain a special character. Or words that contain a number and a special character. Or words that contain a number and a special character and are at least 8 characters long. You get the idea.
For the demonstrations you'll use a mock piece of text that contains e-mails:
let textToSearch = `Lorem ipsum dolor sit amet, consectetur adipiscing elit.
[email protected]
Pellentesque sit amet lacus vitae massa pretium aliquam.
Nulla facilisi. [email protected]
Donec sed dolor ac odio consequat varius.
Integer non lorem lacus. [email protected]
Maecenas non leo laoreet, condimentum lorem nec, vulputate massa.
Quisque mollis dolor non tellus placerat vitae sodales lectus porta.
Curabitur ut suscipit tellus. [email protected]
Phasellus sed sapien eget mi condimentum vehicula.
Nam cursus, diam et lacinia faucibus, [email protected]
Nunc ultrices auctor sapien id cursus.
Aliquam erat volutpat. [email protected]
Morbi in ipsum sit amet pede facilisis laoreet.
Donec lacus nunc, viverra nec, blandit vel, egestas et, augue.
Vestibulum tincidunt malesuada tellus.
Ut ultrices ultrices enim. [email protected]`;
This example will give you some practice in using .search() and .match(). Before you dive into using these methods, though, you'll need to have a regular expression that matches email formats:
\S+@\S+\.\S+
This is a very basic regular expression that matches any string that contains:
- one or more non-whitespace characters (
\S+) - an
@symbol (@) - one or more non-whitespace characters (
\S+) - a
.symbol (\.) - one or more non-whitespace characters (
\S+)
This regular expression will not match all valid emails, but it will match the ones in the example text, and will do for the purposes of this lesson.
One thing to note about this regular expression is that to match multiple occurrences, you need to add the global (g) flag to the regular expression. This flag tells the regular expression to match all occurrences of the pattern in the string. Without this flag, the regular expression will only match the first occurrence of the pattern.
Creating a Regular Expression in JavaScript
The way you turn a primitive JavaScript string into a regular expression is by wrapping it in forward slashes (/). You can also use the RegExp constructor to create a regular expression. Here's an example:
let emailPattern = /\S+@\S+\.\S+/;
// or
let emailPattern = new RegExp("\\S+@\\S+\\.\\S+");
These two lines of code are equivalent. The first one uses the forward slash notation, and the second one uses the RegExp constructor. The second one is a bit more complicated, though, because you need to escape the backslashes. This is because the backslash is a special character in JavaScript strings, so you need to escape it with another backslash.
You can also pass a normal string to the .search() and .match() methods where it will get automatically converted into a RegExp object.
Explicitly creating RegExp objects does give you the opportunity to add things like flags.
With your regular expression in hand, you can now use it to find matches in the text. First off, you may want to find out if the text contains an e-mail at all.
Using .search() to Find the Position of a Regex Match
First up, you'll see if a string contains a substring using the .search() method. This method returns the index of the first match of a substring within a string similar to the .indexOf method. If the substring is not found, then it returns -1.
textToSearch.search(emailPattern); // 57
The .search() method returns the index of the first match of the regular expression within the string. In this case, the first match is at index 57, which is the first character of the first email address.
If the regular expression doesn't match anything, then .search() returns -1:
textToSearch.search(/nomad/); // -1
In this example, you're searching for the string nomad which doesn't exist in the text, so .search() returns -1. Note how you're instantiating the RegExp object directly in the .search() method. This is a shortcut that you can use if convenient.
But say you wanted to find all the email addresses in the text. For that, you'll want to use the .match() method.
Using .match() to Find All Occurrences of Regex Matches
The .match() method returns an array of matches or null if no match is found. First, you'll need to make sure the RegExp object contains the global flag:
let emailPattern = /\S+@\S+\.\S+/g;
// ^
// or
let emailPattern = new RegExp("\\S+@\\S+\\.\\S+", "g");
// ^^^
With the regular expression equipped with the flag you can now use it to find all the matches in the text:
textToSearch.match(emailPattern);
/*
OUTPUT
[
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
]
*/
Nice! An array with all the e-mails in the text! Since the match operation was used with the g flag, you get all the matched strings in an array. If the match operation doesn't find anything, regardless of the g flag, then it returns null:
textToSearch.match(/nomad/g); // null
textToSearch.match(/nomad/); // null
If you don't use the g flag, you'll get a different result. You can simulate this by using the e-mail pattern without the global flag:
textToSearch.match(/\S+@\S+\.\S+/);
/*
OUTPUT
[
'[email protected]',
index: 57,
input: 'Lorem ipsum dolor sit amet, consectetur adipiscing...', (truncated)
groups: undefined
]
*/
The match object is an array-like object that contains the matched string, the index of the match, the input string and an undefined groups property.
Using Capture Groups in JavaScript Regular Expressions
The match object also contains a groups property, which is an object containing the named capture groups. Capture groups are a way to match a pattern and extract a part of the match. This is a bit more advanced, so you won't cover it in detail, but here is a quick example.
To create a capture group in a regular expression you wrap a portion of the pattern in parentheses. For example, to match an email address and extract the username, you could do this:
let match = textToSearch.match(/(\S+)@\S+\.\S+/);
// ^ ^
/*
OUTPUT
[
0: "[email protected]",
1: "contact",
index: 57,
input: "Lorem ipsum dolor sit amet, consectetur adipiscing...", (truncated)
groups: undefined
]
*/
Note how the match object now has two items, the full match at index 0 and the result of the first capture group at index 1. You can have many capture groups in the same regular expression, and they will be captured at each index position. You can also use named capture groups by using the ?<name> syntax:
let match = textToSearch.match(/(?<username>\S+)@\S+\.\S+/);
// ^^^^^^^^^^^^ ^
/*
OUTPUT
{
0: "[email protected]",
1: "contact",
groups: {
username: "contact",
},
index: 57,
input: "Lorem ipsum dolor sit amet, consectetur adipiscing...", (truncated)
}
*/
As you can see, the index positions of the match and the capture group are the same, but the match object now has a groups property that contains the named capture group.
If you want to use capture groups for matching all the occurrences, you need to use the exec() method of the RegExp object instead of match(). This method returns an array of matches, and each match contains the capture groups.
This is how you might set up the exec() method to extract the username from all the e-mails in the text:
let emailPattern = /(\S+)@\S+\.\S+/g; // Ensure you are using the global flag
let match;
while ((match = emailPattern.exec(textToSearch)) !== null) {
console.log('Full match:', match[0]);
console.log('Username:', match[1]);
}
Capture groups can make your regular expressions more powerful, but they can also make them more complicated.
Summary: How to Use the JavaScript match With Regex
In this lesson you got an overview of various methods to match and find strings in JavaScript.
.includes()Method: Used to check the presence of a substring in a string, returning a boolean..indexOf()and.lastIndexOf()Methods: Return the first and last positions of a substring within a string, respectively; return-1if the substring is not found..startsWith()and.endsWith()Methods: Determine if a string starts or ends with a specified substring, respectively, returning a boolean.- Regular Expressions (Regex): Powerful tool for pattern matching in strings; can find complex patterns like email addresses.
.search()and.match()Methods with Regex:.search()finds the first regex match's position, while.match()can return all occurrences of a regex pattern in a string.- Capture Groups in Regex: Allow extraction of parts of the matched string; named capture groups can be used for more clarity.