I’m trying to exclude some internal IP addresses and some internal IP address formats from viewing certain logos and links in the site.I have multiple range of IP addresses(sample given below). Is it possible to write a regex that could match all the IP addresses in the list below using javascript?
10.X.X.X
12.122.X.X
12.211.X.X
64.X.X.X
64.23.X.X
74.23.211.92
and 10 more
Quote the periods, replace the X’s with
\d+, and join them all together with pipes:Then you’re all set:
How it works:
First, we have to turn the individual IP patterns into regular expressions matching their intent. One regular expression for "all IPs of the form ‘12.122.X.X’" is this:
^12\.122\.\d+\.\d+$^means the match has to start at the beginning of the string; otherwise, 112.122.X.X IPs would also match.12etc: digits match themselves\.: a period in a regex matches any character at all; we want literal periods, so we put a backslash in front.\d: shorthand for[0-9]; matches any digit.+: means "1 or more" – 1 or more digits, in this case.$: similarly to^, this means the match has to end at the end of the string.So, we turn the IP patterns into regexes like that. For an individual pattern you could use code like this:
Which just replaces all
.s with\.andXs with\d+and sticks the^and$on the ends.(Note the doubled backslashes; both string parsing and regex parsing use backslashes, so wherever we want a literal one to make it past the string parser to the regular expression parser, we have to double it.)
In a regular expression, the alternation
this|thatmatches anything that matches eitherthisorthat. So we can check for a match against all the IP’s at once if we to turn the list into a single regex of the formre1|re2|re3|...|relast.Then we can do some refactoring to make the regex matcher’s job easier; in this case, since all the regexes are going to have
^...$, we can move those constraints out of the individual regexes and put them on the whole thing:^(10\.\d+\.\d+\.\d+|12\.122\.\d+\.\d+|...)$. The parentheses keep the^from being only part of the first pattern and$from being only part of the last. But since plain parentheses capture as well as group, and we don’t need to capture anything, I replaced them with the non-grouping version(?:..).And in this case we can do the global search-and-replace once on the giant string instead of individually on each pattern. So the result is the code above:
That’s still just a string; we have to turn it into an actual
RegExpobject to do the matching:As written, this doesn’t filter out illegal IPs – for instance,
10.1234.5678.9012would match the first pattern. If you want to limit the individual byte values to the decimal range 0-255, you can use a more complicated regex than\d+, like this:That matches "any one or two digits, or ‘1’ followed by any two digits, or ‘2’ followed by any of ‘0’ through ‘4’ followed by any digit, or ’25’ followed by any of ‘0’ through ‘5’". Replacing the
\dwith that turns the full string-munging expression into this:And makes the actual regex look much more unwieldy:
but you don’t have to look at it, just match against it. 🙂