1st let's understand why the 1st one is working and why the 2nd one is not working.
Example First:
const startsWith = 't'
const contains = 'te'
const re = new RegExp(`(?=.*${contains})^${startsWith}`)
re.test('teacher') // Result = true
Debug:
(?=.*te)^t
Explain:
Here (?=.*te) is "Positive lookahead", which means regex will start matching this and then will look ahead for the next conditions/rules.
(
?= Matches a group after the main expression (^t) without including it in the result.
. DOT, Matches any character except linebreaks
* Matches 0 or more of the preceding token
t Check for character 't'
e Check for character 'e'
)
^ Matches the beginning of the string. This matches a position, not a character.
t Check for character 't'
Human Explain:
Find every string which contains 'te' and ready to look after next rule which is find string which starts with 't'
Hence:
teacher //true, because it has 'te' and starts with 't'
thirdteacher //true, because it has 'te' and starts with 't'
twoteacher //true, because it has 'te' and starts with 't'
myteacher //false, because it has 'te' but does not start with 't'
Example Second:
const endsWith = 'e'
const contains = 'te'
const re = new RegExp(`(?=.*${contains})${endsWith}\$`)
re.test('ate') // Result = false
Debug:
(?=.*te)e$
Explain:
Here (?=.*te) is "Positive lookahead", which means regex will start matching things after the main expression.
(
?= Matches a group after the main expression (e$) without including it in the result.
. DOT, Matches any character except linebreaks
* Matches 0 or more of the preceding token
t Check for character 't'
e Check for character 'e'
)
e Check for character 'e'
$ Matches the end of the string. This matches a position, not a character.
Human Explain:
Find every string which contains 'te' but as the main expression first find a string which ends as the last character 'e'.
it's end man! whoa!! yeah!! end .. end.. nothing after to match... it's ending.
- Since... "Positive lookahead" failed here due to the main expression
ends the search here using '$'
Hence "Positive lookahead" can not proceed for "lookahead"
Hence:
regex will find ... nothing, no match Ssshhhh... silence
So what is the solution?
You have 2 options either use @The fourth bird solution which is '(?=.*te).*e$' in debug mode.
Here '.' is the main expression and gives "Positive lookahead" a chance to move and find strings and matches after ..
(
?= Matches a group after the main expression (e$) without including it in the result.
. DOT, Matches any character except linebreaks
* Matches 0 or more of the preceding token
t Check for character 't'
e Check for character 'e'
)
. DOT, Matches any character except linebreaks
* Matches 0 or more of the preceding token
e Check for character 'e'
$ Matches the end of the string. This matches a position, not a character.
Human Explain:
Hey! regex please bring me a string which contains 'te' and ends with 'e'
Execution Pipeline for 'soulmate':
(?=.*te) -- did you found 'te' yes 'solema*te*'
.* -- main expression is find everything, did you found, yes 'soulmate'
e$ -- last expression is 'ends with e', did you find, yes 'soulmat*e*'
Master, here is the result - 'soulmate'
// false tomato page
// false yellow-teeth
// true teeth-color-is-white
// true ate
// false future terminator
// false AI is awful and should never be replaced with the human race.
// true AI is good for telephones but awful for the human race
// true I am running late
// true e-gate
// true soulmate
// false time
// false race
// false ate-milan-cafes
// true tell me the truth if mighty god is everywhere
Another option is using the native Javascript function. startsWith, includes and endsWith.
Example:
<script>
var first = "teacher";
var startwith = first.startsWith("t");
var contains = first.includes("te");
alert((contains && startwith)); // true
var second = "ate";
var contains = first.includes("te");
var endwith = second.endsWith("e");
alert((contains && endwith)); // true
</script>