Sometimes you need to solve a problem
of this type: find the string 'aaa'
and replace it with '!'
, but only
if after 'aaa'⁅/s ⁆ is
,
while 'x'
'x'
itself is not replaced. If
we try to solve the problem 'head-on'
,
then nothing will come of it:
'aaax baaa'.replace(/aaax/g, '!'); // returns '! baaa', but we wanted '!x baaa'
Lookahead
To solve the problem, we need a way
to say that 'x'
should not
be replaced. This is done with the
special parentheses (?= )
,
which just look at, but don't take
with them.
These parentheses are called
positive lookahead. Positive
- since 'x'
(in our case)
should be - only then replacement
will occur.
Let's use these parentheses to solve our problem:
'aaax aaab'.replace(/aaa(?=x)/g, '!'); // returns '!x aaab'
There is also negative lookahead
- (?! )
- on the contrary, it
says that something should not be. In
the following example, the replacement
will only occur if 'aaa'
is
NOT followed by 'x'
:
'aaax aaab'.replace(/aaa(?!x)/g, '!'); // returns 'aaax !b'
Lookbehind
Similarly, there is
positive lookbehind - (?<= )
. In
the following example, the replacement
will only occur if 'aaa'
is
preceded by 'x'
:
'xaaa'.replace(/(?<=x)aaa/g, '!'); // returns 'x!'
And there is also
negative lookbehind - (?<! )
. In
the following example, the replacement
will only occur if 'aaa'
is
not preceded by 'x'
:
'baaa'.replace(/(?<!x)aaa/g, '!'); // returns 'b!'
Practical tasks
Given a string containing function names:
let str = 'func1() func2() func3()';
Get an array of the function names from the string.
Given a string with a tag:
let str = '<a href="" class="eee" id="zzz">';
Get an array of attribute names for this tag.
Given a string with variables:
let str = '$aaa $bbb $ccc xxxx';
Get substrings preceded by a dollar sign.