The fault is definitely in your regex: it's pathologically inefficient. Basically, you've got multiple consecutive parts that can match the same characters, all controlled by open-ended quantifiers (*
and +
). This creates an astronomical number of "paths" the regex has to check before it gives up on the match. In fact, this sort of problem usually becomes apparent only when no match is possible, but you've managed to trigger it on a regex that should match.
I suspect you were trying for something like this:
/^[a-z]+(?:[_.-][a-z]+)*@[a-z]+(?:\.[a-z]+)*$/i
Before anyone starts criticizing, I know [a-z]+
is no more correct than \S+
. I'm just trying to explain what's wrong with his regex. The idea is to force the user name and the domain name to start with letters, while allowing them to be separated into chunks around delimiters like .
, -
, and _
. That's what makes it so complicated
The most important feature of this regex is that it always moves forward. When [a-z]+
runs out of letters to consume, the next thing it sees must be one of the delimiter characters, an at-sign ('@'), or the end of the string (depending on which part of address it's matching). If it doesn't see what it expects, the match attempt fails immediately.
In your regex the \S+
part initially gobbles up the whole string, then starts backing off one character at a time to give the next part a chance to match. This process is repeated for every \S+
. As HamZa observed, that's where the regex engine spends most of its time. But it's not the \S+
alone that's killing you, it's the structure of the regex.