我试图使用regex.h
但没有成功。我试图匹配IP地址
#include <stdio.h>
#include <regex.h>
#define No_Regex_Flags 0
void check_RE(char * r, regex_t RE)
{
printf ("%s - %s\n", r, !regexec(&RE, r, 0, NULL, 0) ? "Match" : "No Match");
}
int main ()
{
regex_t regex;
int ret = regcomp(®ex, "[0-9]{1,3}.{3}[0-9]{1,3}", No_Regex_Flags);
if(ret)
printf("err1\n");
char RE_list[][32] =
{
"0.0.0.0",
"123.456.789.123",
"a.b.c.d",
"1.2.34.567",
"1111.1.1.1",
".1.1.1",
"1,1,1,1"
};
for(int i = 0; i < sizeof(RE_list) / sizeof(RE_list[0]); i++)
check_RE(RE_list[i], regex);
return 0;
}
然而,我得到的输出总是匹配:
0.0.0.0 - Match
123.456.789.123 - Match
a.b.c.d - Match
1.2.34.567 - Match
1111.1.1.1 - Match
.1.1.1 - Match
1,1,1,1 - Match
为什么?
答案 0 :(得分:3)
使用
int ret = regcomp(®ex, "^([0-9]{1,3}\\.){3}[0-9]{1,3}$", REG_EXTENDED);
或者,效率更高:
int ret = regcomp(®ex, "^[0-9]{1,3}(\\.[0-9]{1,3}){3}$", REG_EXTENDED);
请参阅this regex demo,其中也包含错误的IP地址,例如1.2.34.567
和123.456.789.123
。所以,我建议更准确一个(来源:regular-expresions.info):
"^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$"
请参阅this regex demo。
请参阅C demo。输出是
0.0.0.0 - Match
123.456.789.123 - No Match
a.b.c.d - No Match
1.2.34.567 - No Match
1111.1.1.1 - No Match
.1.1.1 - No Match
1,1,1,1 - No Match
<强>的POI 强>
\\
对其进行转义
[0-9]{1,3}\\.{3}
=&gt; ([0-9]{1,3}\\.){3}
^
和$
$
锚定工作,您需要将REG_EXTENDED
标记传递给regcomp
。如果您打算使用{3}
而无需转义{
和}
,也需要它。否则,您必须遵循BRE POSIX规范并编写限制量词,如\{3\}
[0-9]{1,3}
匹配任意3位数,原始模式并未真正验证IP地址,因此您需要将八位字节值限制为0
.. 255
。因此,应使用替换组(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])
来匹配一个八位字节。这是八位字节模式说明:
25[0-5]
- 250
至255
|
- 或2[0-4][0-9]
- 200
至249
|
- 或1[0-9][0-9]
- 100
至199
|
- 或[1-9]?[0-9]
- 0
至99
。