Assertions
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).
Try it
Types
Boundary-type assertions
Characters | Meaning |
---|---|
^ |
Input boundary beginning assertion:
Matches the beginning of input. If the Note: This character has a different meaning when it appears at the start of a character class. |
$ |
Input boundary end assertion:
Matches the end of input. If the |
\b |
Word boundary assertion: Matches a word boundary. This is the position where a word character is not followed or preceded by another word-character, such as between a letter and a space. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. Examples:
To match a backspace character ( |
\B |
Non-word-boundary assertion:
Matches a non-word boundary. This is a position where the previous and
next character are of the same type: Either both must be words, or
both must be non-words, for example between two letters or between two
spaces. The beginning and end of a string are considered non-words.
Same as the matched word boundary, the matched non-word boundary is
also not included in the match. For example,
|
Other assertions
Note:
The ?
character may also be used as a quantifier.
Characters | Meaning |
---|---|
x(?=y) |
Lookahead assertion:
Matches "x" only if "x" is
followed by "y". For example, |
x(?!y) |
Negative lookahead assertion:
Matches "x" only if "x"
is not followed by "y". For example, |
(?<=y)x |
Lookbehind assertion:
Matches "x" only if "x" is
preceded by "y". For example,
|
(?<!y)x |
Negative lookbehind assertion:
Matches "x" only if
"x" is not preceded by "y". For example,
|
Examples
General boundary-type overview example
// 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'.
Matching the beginning of input using a ^ control character
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.
Matching a word boundary
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((descr) =>
/(en|ed)\b/.test(descr),
);
console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
See more examples in the word boundary assertion reference.
Lookahead assertion
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.
Basic negative lookahead assertion
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.
Different meaning of '?!' combination usage in assertions and character classes
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!' ]
Lookbehind assertion
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.