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.