views:

310

answers:

9

How can I determine if a string is an IP? Either IPv4 or IPv6?

What is the least and most number of characters?

I assume this would be a regex answer.

+3  A: 

For IPv4 you can use this regular expression.

\b(?:(?: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]?)\b

It looks quite complex but it works by limiting each quad to the numbers 0-255.

Bill the Lizard
+3  A: 

But the question is not as simple as assuming a.b.c.d ... there are way more forms than you realised.

But surely this is a Google for it question? Pretty much every regex primer you can find anywhere uses IP as an example! ipv4 + regex scores 183,000 hits!

Unsliced
Yes, but the problem is that, given a string, how can one recognize if it is an IPv4 or IPv6? And after that, parse it.
pek
But since the link you provided is a great article, I chose this as the correct answer. ;)
pek
A: 

Since half of that regex handles the fact that the last segment doesn't have a period at the end, you could cut it in half if you tack a '.' to the end of your possible IP address.

Something like this:

bool IsValidIPAddress(string possibleIP){
  CrazyRegex = \b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){4}\b
  return Regex.Match(possibleIP+'.', CrazyRegex)
}
Michael Haren
A: 

@unsliced: true, this problem can get a little crazy.

If you really need to handle any possible IP address then you'll have to put together something more sophisticated.

However, if you just want to do basic validation to make sure users are entering properly formatted data, I think it's fair to restrict them to the a.b.c.d model with the above regular expressions.

Michael Haren
A: 

@unsliced that is correct however it will of course depend on implementation, if you are parsing an IP from a user visiting your site then your are fine to use regex as it SHOULD be in x.x.x.x format.

For IPv6 you could use this

[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}:[A-F0-9]{0,4}

however it does not catch everything because with IPv6 it is much more complicated, acording to wikipedia all of the following examples are technicaly correct however the regex above will only catch the ones with a *

2001:0db8:0000:0000:0000:0000:1428:57ab*
2001:0db8:0000:0000:0000::1428:57ab*
2001:0db8:0:0:0:0:1428:57ab*
2001:0db8:0:0::1428:57ab
2001:0db8::1428:57ab
2001:db8::1428:57ab
Unkwntech
+5  A: 

In .NET there's an IPAddress type which has a handy method TryParse.

Example:

if(System.Net.IPAddress.TryParse(PossibleIPAddress, validatedIPAddress)){
    //validatedIPAddress is good
}

// or more simply:
bool IsValidIPAddress(string possibleIP){
    return System.Net.IPAddress.TryParse(PossibleIPAddress, null)
}
Michael Haren
+3  A: 

I've done this before, but I like Raymond Chen's post at:

http://blogs.msdn.com/oldnewthing/archive/2006/05/22/603788.aspx

Where he basically advocates using regexes for what they're good at: parsing out the tokens. Then evaluate the results. His example:

function isDottedIPv4(s)
{
 var match = s.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
 return match != null &&
        match[1] <= 255 && match[2] <= 255 &&
        match[3] <= 255 && match[4] <= 255;
}

It's much easier to look at that and grok what it's supposed to be doing.

Niniki
A: 

So, since Unkwntech's method doesn't work 100% of the times, any other suggestions for IPv6?

And because some have posted language specific answers, I am particularly interested in php... So any luck there?

pek
A: 

IPv4 becomes: /\d\d?\d?.\d\d?\d?.\d\d?\d?.\d\d?\d?/

I'm not sure about the IPv6 rules.

Dough