The default regular expressions are greedy. This means that they capture the maximum possible number of characters. Let's take a look at an example. Let's say we have this string:
let str = 'aeeex zzz x kkk';
Suppose we want to find the substring 'aeeex'
in
this string using the following pattern: letter
'a'
, then any character one or more times,
then letter 'x'
.
let res = str.replace(/a.+x/g, '!');
We expect the string '! zzz x kkk'
to be
written to the variable as a result. However,
this is not the case - the string '! kkk'
gets into the variable.
The thing is that our regex searches for all
characters from the letter 'a'
to the
letter 'x'
. But our string has two
letters 'x'
! Because of greed, it turns
out that the regex searches until the very last
'x'
, thereby capturing not what we expected.
Of course, often we want this behavior. But
specifically in this case, we would like to
cancel the greed and tell the regex to search
until the first 'x'
.
To limit greed, you need to put a question mark after the repetition operator:
let res = str.replace(/a.+?x/g, '!');
Greediness can be limited for all repetition
operators: *
, and ?
, and
{}
- like this: *?
, ??
and {}?
.
Given a string:
let str = 'aba accca azzza wwwwa';
Write a regex that will find all strings with
the letters 'a'
at the edges and replace
each of them with '!'
. Between the letters
'a'
there can be any character
(except 'a'
).