正则表达式匹配错误的字符串

时间:2018-05-30 07:26:09

标签: c regex

我试图使用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(&regex, "[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

为什么?

1 个答案:

答案 0 :(得分:3)

使用

int ret = regcomp(&regex, "^([0-9]{1,3}\\.){3}[0-9]{1,3}$", REG_EXTENDED);

或者,效率更高:

int ret = regcomp(&regex, "^[0-9]{1,3}(\\.[0-9]{1,3}){3}$", REG_EXTENDED);

请参阅this regex demo,其中也包含错误的IP地址,例如1.2.34.567123.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] - 250255
  • | - 或
  • 2[0-4][0-9] - 200249
  • | - 或
  • 1[0-9][0-9] - 100199
  • | - 或
  • [1-9]?[0-9] - 099