I have a regex that i ended up using from one of the answer here in SO . Basically my regex must validate ipv4 address with mask .
So i ended up using the below regex :
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/([1-9]|1[0-9]|2[0-9]|3[0-2]|(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254))))
Now my challenge is to not allow 0 in the last digit of ip i.e ,
192.168.6.10/mask
is valid but 192.168.6.0/mask
is invalid
So i modified the above regexp to something like this :
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[1-9]?)/([1-9]|1[0-9]|2[0-9]|3[0-2]|(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254))))
but 192.168.6.0
is always valid when testing with Angular Validators.pattern
Any idea where i'm going wrong ?
EDIT List of IPs & its validity :
192.168.6.6/24 is valid 192.168.6.6/24 is valid 192.168.6.24/24 is valid
192.168.6.0/24 invalid 192.168.6.0/255.255.255.0 is invalid
You want to avoid matching any IP with the last octet set to 0
.
You may use
ipAddress : FormControl = new FormControl('' , Validators.pattern(/^(?!(?:\d+\.){3}0(?:\/|$))(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(?:[1-9]|1[0-9]|2[0-9]|3[0-2]|(?:(?:128|192|224|240|248|252|254)\.0\.0\.0|255\.(?:0|128|192|224|240|248|252|254)\.0\.0|255\.255\.(?:0|128|192|224|240|248|252|254)\.0|255\.255\.255\.(?:0|128|192|224|240|248|252|254)))$/));
Here is the regex demo
The main addition is the lookahead after ^
that is executed once at the start of a string. The (?!(?:\d+\.){3}0(?:\/|$))
pattern is a negative lookahead that fails the match if, immediately to the right of the current location (string start), there are:
(?:\d+\.){3}
- three repetitions of 1+ digits and a dot0
- a zero(?:\/|$))
- /
or (|
) end of string ($
).Notice I defined the pattern using a regex literal notation (/regex/
) and I had to add ^
(string start) and $
(string end) anchors since the regex was no longer anchored by default. Also, to escape special chars in a regex literal notation, you only need one backslash, not two.