2

Hi my regex pattern is

^((?:(?:^|\.)(?:\d|[1-9]\d|1\d{2}|2[-4]\d|25[0-5])){4})$

this allow 0.0.0.0 but i do not want to allow 0.0.0.0 please someone help me

karthik manchala
  • 13,492
  • 1
  • 31
  • 55
Ravendra Kumar
  • 1,072
  • 10
  • 29
  • Do you need to allow: `1.0.0.0`, `0.1.0.0`, `0.0.1.0`, `0.0.0.1`? (in other words, if there is only one number not equal to zero, can it be at any position?) – Casimir et Hippolyte May 26 '15 at 09:23

4 Answers4

2

Just add a negative lookahead assertion at the start.

^(?!0+\.0+\.0+\.0+$)((?:(?:^|\.)(?:\d|[1-9]\d|1\d{2}|2[-4]\d|25[0-5])){4})$

DEMO

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
2
^(?=.*[1-9])((?:(?:^|\.)(?:\d|[1-9]\d|1\d{2}|2[-4]\d|25[0-5])){4})$

You can do this through positive lookahead.See demo.

https://regex101.com/r/yW3oJ9/8

vks
  • 67,027
  • 10
  • 91
  • 124
  • 2
    I know it might not be the case, but this regex is prone to catastrophic backtracking in some very [weird scenarios like this](https://regex101.com/r/yE3oO3/1). Perhaps, the string is not a user's input and will never occur. However, my suggestion works ok even in such cases. Avinash's is also performing great. In general, I'd avoid `.*` if it is not necessary. – Wiktor Stribiżew May 26 '15 at 09:19
  • @stribizhev hehehe.........i suspect, that ip address would be possible in year 3050 when population is billions :P – vks May 26 '15 at 09:23
0

A look-ahead can be used to set a length limit. In this case, it can be quite concise, since the string should only contain digits and . symbol.

Thus, I suggest using (?![0.]+$) as we only need to check if we have no 0s and periods up to the end:

^(
 (?![0.]+$)                  # Here is the look-ahead.
 (?:
   (?:^|\.)
   (?:
      \d|[1-9][0-9]|1\d{2}|2[-4]\d|25[0-5]
   )
 ){4}
)$

See demo

A one-line JS version:

^((?![0.]+$)(?:(?:^|\.)(?:\d|[1-9][0-9]|1\d{2}|2[-4]\d|25[0-5])){4})$
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

Is this part of an assignment?

If not, I would use no regex and prefer String#scan :

ip_subnets = ip.scan(/\d+/).map(&:to_i) # you can use split('.') instead of scan
ip_subnets.all? { |i| (0..255).include?(i) } && 
  ip_subnets.any? { |i| i != 0 } && 
  ip_subnets.size == 4
floum
  • 1,149
  • 6
  • 17