Reputation: 2841
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
Upvotes: 1
Views: 664
Reputation: 627419
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.
Upvotes: 1
Reputation: 26153
Suppose that the last part cannot be written 000
and 00
but just 0
. Then you can you such regex
^(?:(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)\.){3}(?:(?:2(?:5[0-5]|[0-4]\d)|1?\d\d|[1-9]))$
Where diff between the first groups and the last one that one-digit value should be from 1 to 9
Upvotes: 1
Reputation: 522636
One possible approach here is simple, and just involves adding a negative lookbehind at the very end of the pattern (?<!\.0)
, which asserts that .0
is not the immediately preceding term in the IP address. Applying this to your correctly working pattern from the comments above, we get:
^(?:(?: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))))(?<!\.0)$
The downside is that your JavaScript engine may not yet support negative lookbehind syntax just yet.
Upvotes: 0
Reputation: 5921
You can try with this pattern
^(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:2[0-5][1-5]|[1-9]|1[0-9][1-9]|[1-9][1-9])$
Online demo
For the last numbers you have check with this
(?:2[0-5][1-5]|[1-9]|1[0-9][1-9]|[1-9][1-9])
Upvotes: 0