I created this regex in Javascript that returns a boolean for Domain validation that meets the criteria to allow IP addresses and ascii domain name. The assumption is that the TLD should be atleast two letters.


I used the following Javascript to test the regex:

var func = function(val) { return /^((([0-9]{1,3}\.){3}[0-9]{1,3})|(([a-zA-Z0-9]+(([\-]?[a-zA-Z0-9]+)*\.)+)*[a-zA-Z]{2,}))$/.test(val);}

It works correctly:

   func('') //return true; 
   func('a-a.com')     //returns true;
   func('aa.com')      //returns true;
   func('aa.cc')       //returns true;
   func('aa.c')        //returns false;

I have basic knowledge of regex's and hence seeing if there anyway to optimize it.

  • \$\begingroup\$ Let me guess, that's for validating email addresses? If so, then this is probably relevant \$\endgroup\$ Sep 2, 2016 at 17:36
  • \$\begingroup\$ I edited my question and removed the leading @ to avoid the confusion. \$\endgroup\$ Sep 2, 2016 at 19:50
  • \$\begingroup\$ 1. What about international host names prior to encoding? 2. Domain name is not the same as host name. More info: stackoverflow.com/a/14622263 \$\endgroup\$
    – woxxom
    Sep 3, 2016 at 7:48
  • 1
    \$\begingroup\$ Also note that currently invalid IP's will be accepted: func('999.999.999.999'); will return true! \$\endgroup\$
    – cFreed
    Sep 3, 2016 at 13:17
  • \$\begingroup\$ Why not use separate regex for IP and domain? And as pointed the IP regex is accepting invalid IPs. See this regex \$\endgroup\$
    – Tushar
    Sep 6, 2016 at 7:34

1 Answer 1


Your regex will suffer from catastrophic backtracking with certain inputs. Just try matching aaaaaaaaaaaaaaaaaaaaaaaaaaaa, and you'll see the visible slowdown.

I suggest (as was already mentioned in the comments) that you break up the regex at the | into two separate regexes, one for IP addresses and the other for domain names. It just makes more sense, especially from a future maintainability perspective, and will make things easier for you in the future.

The IP address part is actually very efficient on its own, so there are no further changes I would make to this part:


The second part of the regex is the source of the slowdown. It also matches some strange things, like this:


I'm just going to assume that these are bugs, although I don't know given that you haven't made it clear what should match. That's why I will write up some rules for what I want to match:

  • Must start with an alphanumeric
  • There may be . or - characters, but they must be surrounded by alphanumerics.
  • Must end with . followed by two or more letters

Here is the regex that would be (with newlines added for emphasis):


Note that - does not need to be escaped if it's the first thing in the character class. . is never a metacharacter in character classes.

Finally, I would use the i modifier to get rid of all the a-zA-Z redundancy:


Here are the tests:




The first group is matched by both, the second group is matched by only your regex, and the last group is matched by neither.

To show you the difference in performance, I tested against this variation of your original regex:


Using the PCRE option on Regex101 (with the gm options), your regex takes 66390 steps. The new regex I wrote took only 214 steps, and it's shorter and more legible too.

  • \$\begingroup\$ Excellent, remarkable analysis! \$\endgroup\$ Jun 4, 2019 at 10:29
  • \$\begingroup\$ Thank you for your regex! I would like to allow multiple dashes (per spec) and I came up with the following modification. Do you see any issues with it? /^[a-z0-9]+(([-]*.)[a-z0-9]+)*\.[a-z]{2,}$/i \$\endgroup\$
    – hndcrftd
    Dec 26, 2019 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.