It's as simple as removing the optional quantifier (?
) from behind the space:
/^[a-zA-Z0-9]+([ ][a-zA-Z0-9]+)*$/
should be fine.
We need to argue two things:
- This doesn't change what the RegEx matches: The optional quantifier was unnecessary. The Kleene star (
*
) already makes the entire space-delimited part (([ ][a-zA-Z0-9]+)
) optional. If there is no space, you'd have just alphanumerics, which the [a-zA-Z0-9]+
would've matched.
- This changes the runtime drastically: A character is either a space or matches
[a-zA-Z0-9]
. There are no "ambiguities"; there is only one state the RegEx engine can advance into: If it is an alphanumeric, it must stay in the greedy quantifier; if it is a space, it must advance, and then expect at least one alphanumeric. In particular, what can't happen anymore is that the RegEx engine has two options: Whether to enter another iteration of the Kleene star or stay in the current [a-zA-Z0-9]+
.
I've applied some more changes, moving the Kleene star to the front and using the i
flag to shorten it further (you can then omit the A-Z
). The [
and ]
brackets around the space were also unnecessary. Using The fourth bird's tests, here's how it performs: /^([a-z0-9]+ )*[a-z0-9]+$/i
.
Like your current RegEx, this doesn't enforce the length requirement. I'd recommend enforcing the length requirement in JavaScript before testing against the RegEx. This will be the most readable & efficient.