Reputation: 356
I am trying to validate IP address input in C. Here is my code
char* messType;
regex_t regex;
int regres;
char msgbuf[100];
/* Compile regular expression */
regres =
regcomp(®ex,
"^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", 0);
if (regres)
{
fprintf(stderr, "Could not compile regex\n");
exit(1);
}
regres = regexec(®ex, servIP, 0, NULL, 0);
if( regres == REG_NOMATCH )
{
puts("Invalid IP address");
exit(EXIT_FAILURE);
}
else
{
regerror(regres, ®ex, msgbuf, sizeof(msgbuf));
fprintf(stderr, "Regex match failed: %s\n", msgbuf);
exit(1);
}
However, this failed every IPV4 address I entered.
Upvotes: 2
Views: 5145
Reputation: 356
I actually figured out what was wrong with this code.
regcomp(®ex,
"^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))."
"([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))$", REG_EXTENDED);
The cflag is REG_EXTENDED not 0
Upvotes: 1
Reputation: 42899
If I were you, I would separate the syntactic and the semantic validation.
Syntactically, in the context of your question, an IP address is a string made of four decimal numbers separated by dots, so a simple regular expression can be used:
([0-9])\.([0-9])\.([0-9])\.([0-9])
Semantically, an IP address is a 32-bit number so each byte can only be in the range [0, 255].
As soon as you can retrieve each captured sub-pattern, just convert each number string to an integer using for example the atoi function and check whether it is effectively in the range.
The semantical analysis is very useful if you need to check for special IP values, like broadcast addresses (255.255.255.255
), or private network addresses (10.x.x.x
, etc).
Upvotes: 1
Reputation: 70929
I would say regular expressions are not the best option to validate IP address. As there is a limit on the valid values between the dots it will be hard to express that with regex. The expression will get quite lenghty and one could easily make an error in this.
And even if above argument is not good enough, try to write a regex for IPv6. It gets even worse...
Upvotes: 3