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
- 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):
- 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
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.