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

标签 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

这是为什么?

最佳答案

使用

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

兴趣点

  • 点匹配任何字符,所以你必须在模式中用 \\ 转义它
  • 如果您必须重复一系列模式,则需要将它们分组并量化该组:[0-9]{1,3}\\.{3} => ([0-9]{1,3}\\.){3}
  • 要匹配整个字符串,您需要 anchor ^ 和围绕模式的$
  • 要使 $ anchor 工作,您需要将 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

关于c - 正则表达式匹配错误的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50598736/

相关文章:

C99 const 按值传递

c - 为什么在尝试释放字符串数组时出现此错误

regex - 用编码字符串替换 URL 的多个部分

regex - 正则表达式 |删除给定单词前多行的单词

用于验证属性路由正则表达式约束中不带引号的字母数字 csv 列表的正则表达式

c++ - 位字段类型是否需要相同?

c - 如何将 MD5 生成的十六进制值存储为整数?

c++ - char* 和 wchar_t* 的区别

python - 正则表达式仅提取单词

regex - 是否可以使用正则表达式来匹配条件?