files/en-us/web/javascript/guide/regular_expressions/assertions/index.md
Assertions include boundaries, which indicate the beginnings and endings of lines and words, and other patterns indicating in some way that a match is possible (including look-ahead, look-behind, and conditional expressions).
{{InteractiveExample("JavaScript Demo: RegExp Assertions", "taller")}}
const text = "A quick fox";
const regexpLastWord = /\w+$/;
console.log(text.match(regexpLastWord));
// Expected output: Array ["fox"]
const regexpWords = /\b\w+\b/g;
console.log(text.match(regexpWords));
// Expected output: Array ["A", "quick", "fox"]
const regexpFoxQuality = /\w+(?= fox)/;
console.log(text.match(regexpFoxQuality));
// Expected output: Array ["quick"]
<table class="standard-table"> <thead> <tr> <th scope="col">Characters</th> <th scope="col">Meaning</th> </tr> </thead> <tbody> <tr> <td><code>x(?=y)</code></td> <td> <p> <a href="/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookahead_assertion"><strong>Lookahead assertion:</strong></a> Matches "x" only if "x" is followed by "y". For example, <code>/Jack(?=Sprat)/</code> matches "Jack" only if it is followed by "Sprat". <code >/Jack(?=Sprat|Frost)/</code > matches "Jack" only if it is followed by "Sprat" or "Frost". However, neither "Sprat" nor "Frost" is part of the match results. </p> </td> </tr> <tr> <td><code>x(?!y)</code></td> <td> <p> <a href="/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookahead_assertion"><strong>Negative lookahead assertion:</strong></a> Matches "x" only if "x" is not followed by "y". For example, <code>/\d+(?!\.)/</code> matches a number only if it is not followed by a decimal point. <code >/\d+(?!\.)/.exec('3.141')</code > matches "141" but not "3". </p> </td> </tr> <tr> <td><code>(?<=y)x</code></td> <td> <p> <a href="/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion"><strong>Lookbehind assertion:</strong></a> Matches "x" only if "x" is preceded by "y". For example, <code>/(?<=Jack)Sprat/</code> matches "Sprat" only if it is preceded by "Jack". <code>/(?<=Jack|Tom)Sprat/</code> matches "Sprat" only if it is preceded by "Jack" or "Tom". However, neither "Jack" nor "Tom" is part of the match results. </p> </td> </tr> <tr> <td><code>(?<!y)x</code></td> <td> <p> <a href="/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Lookbehind_assertion"><strong>Negative lookbehind assertion:</strong></a> Matches "x" only if "x" is not preceded by "y". For example, <code>/(?<!-)\d+/</code> matches a number only if it is not preceded by a minus sign. <code>/(?<!-)\d+/.exec('3')</code> matches "3". <code>/(?<!-)\d+/.exec('-3')</code> match is not found because the number is preceded by the minus sign. </p> </td> </tr> </tbody> </table>[!NOTE] The
?character may also be used as a quantifier.
// Using Regex boundaries to fix buggy string.
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;
// 1) Use ^ to fix the matching at the beginning of the string, and right after newline.
buggyMultiline = buggyMultiline.replace(/^t/gim, "h");
console.log(1, buggyMultiline); // fix 'tey' => 'hey' and 'tangs' => 'hangs' but do not touch 'traa'.
// 2) Use $ to fix matching at the end of the text.
buggyMultiline = buggyMultiline.replace(/aa$/gim, "ee.");
console.log(2, buggyMultiline); // fix 'traa' => 'tree.'.
// 3) Use \b to match characters right on border between a word and a space.
buggyMultiline = buggyMultiline.replace(/\bi/gim, "t");
console.log(3, buggyMultiline); // fix 'ihe' => 'the' but do not touch 'light'.
// 4) Use \B to match characters inside borders of an entity.
fixedMultiline = buggyMultiline.replace(/\Bo/gim, "e");
console.log(4, fixedMultiline); // fix 'greon' => 'green' but do not touch 'on'.
Use ^ for matching at the beginning of input. In this example, we can get the fruits that start with 'A' by a /^A/ regex. For selecting appropriate fruits we can use the filter method with an arrow function.
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Select fruits started with 'A' by /^A/ Regex.
// Here '^' control symbol used only in one role: Matching beginning of an input.
const fruitsStartsWithA = fruits.filter((fruit) => /^A/.test(fruit));
console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
In the second example ^ is used both for matching at the beginning of input and for creating negated or complemented character class when used within character classes.
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Selecting fruits that do not start by 'A' with a /^[^A]/ regex.
// In this example, two meanings of '^' control symbol are represented:
// 1) Matching beginning of the input
// 2) A negated or complemented character class: [^A]
// That is, it matches anything that is not enclosed in the square brackets.
const fruitsStartsWithNotA = fruits.filter((fruit) => /^[^A]/.test(fruit));
console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
See more examples in the input boundary assertion reference.
In this example, we match fruit names containing a word that ends in "en" or "ed".
const fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
// Select descriptions that contains 'en' or 'ed' words endings:
const enEdSelection = fruitsWithDescription.filter((description) =>
/(?:en|ed)\b/.test(description),
);
console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
See more examples in the word boundary assertion reference.
In this example, we match the word "First" only if it is followed by the word "test", but we do not include "test" in the match results.
const regex = /First(?= test)/g;
console.log("First test".match(regex)); // [ 'First' ]
console.log("First peach".match(regex)); // null
console.log("This is a First test in a year.".match(regex)); // [ 'First' ]
console.log("This is a First peach in a month.".match(regex)); // null
See more examples in the lookahead assertion reference.
For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec('3.141') matches "141" but not "3.
console.log(/\d+(?!\.)/g.exec("3.141")); // [ '141', index: 2, input: '3.141' ]
See more examples in the lookahead assertion reference.
The ?! combination has different meanings in assertions like /x(?!y)/ and character classes like [^?!].
const orangeNotLemon =
"Do you want to have an orange? Yes, I do not want to have a lemon!";
// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and Ranges /[^?!]/
const selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
const selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
In this example, we replace the word "orange" with "apple" only if it is preceded by the word "ripe".
const oranges = ["ripe orange A", "green orange B", "ripe orange C"];
const newFruits = oranges.map((fruit) =>
fruit.replace(/(?<=ripe )orange/, "apple"),
);
console.log(newFruits); // ['ripe apple A', 'green orange B', 'ripe apple C']
See more examples in the lookbehind assertion reference.