Remove ?
after each [.-]
:
/^\w+(?:[.-]\w+)*@\w+(?:[.-]\w+)*(?:\.\w{2,8})+$/
See the regex demo
In ([.-]?\w+)*
, the [.-]?
matches 1 or 0 occurrences of .
or -
, and the whole group pattern gets reduced to (\w+)*
after \w+
, it causes too many redundant backtracking steps.
Also, it is a good idea to use non-capturing groups if you are only using the grouping construct to quantify a group of subpatterns.
Now, regarding
it must have letter(s) then @ then letter(s) then . then letter(s) and must not be too long
I see others suggest ^\S+@\S+\.\S+$
like solutions, which is a good idea, just make sure you understand that \S
matches any char other than whitespace (not just letters). Besides, this does not actually provide the final solution since "must not be too long" condition is not met (+
matches from 1 to quite many occurrences, that is why it is described as 1 or more).
I suggest using the pattern inside an HTML5 pattern attribute and restrict the number of chars a user can type with maxlength
attribute:
input:valid {
color: black;
}
input:invalid {
color: red;
}
<form name="form1">
<input pattern="\S+@\S+\.\S+" maxlength="256" title="Please enter an email address like name@myhost.com!" placeholder="name@myhost.com"/>
<input type="Submit"/>
</form>
NOTE: the pattern regex is compiled by enclosing the pattern with ^(?:
and )$
, you do not need to use ^
and $
in the regex here. So, pattern="\S+@\S+\.\S+"
is translated into:
^(?:
(this is added by HTML5) - start of a string (and a non-capturing group starts)
\S+
- any 1 or more non-whitespace chars
@
- a @
char
\S+
- any 1 or more non-whitespace chars
\.
- a dot
\S+
- any 1 or more non-whitespace chars
)$
(this is added by HTML5) - the non-capturing group ends and the end of a string is matched.