C POSIX正则表达式失败

时间:2015-12-06 12:31:47

标签: c regex posix

我正在尝试在C编程语言中使用POSIX正则表达式。

我有这些正则表达式模式:

const char *regular_expression_pattern_keyword = "^(auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)";
const char *regular_expression_pattern_identifier = "^[:word:]";
const char *regular_expression_pattern_number = "^[:digit:]*";
const char *regular_expression_pattern_punctuator = "^[:punct:]";

检查雷鬼,我有一个功能:

char **patterns = malloc ((sizeof (char) * 256) * 4);

patterns[0] = (char *) regular_expression_pattern_keyword;
patterns[1] = (char *) regular_expression_pattern_identifier;
patterns[2] = (char *) regular_expression_pattern_number;
patterns[3] = (char *) regular_expression_pattern_punctuator;

for (int i = 0; i < 4; i++)
{
    regex_t regular_expression;
    int status;

    status = regcomp(&regular_expression, patterns[i], 0);

    if (status)
    {
        // FIXME: Improve error handling!
        printf("Error: Failed to compile regex!\n");
        exit(1);
    }

    status = regexec(&regular_expression, "auto", 0, NULL, 0);

    if (!status)
    {
        printf("Regex status: Match ->%s\n", patterns[i]);
    }

    else if (status == REG_NOMATCH)
    {
        printf("Regex status: No match\n");
    }

    else
    {
        // FIXME: Improve error handling!
        printf("Error: Failed to match regex!\n");
        exit(1);
    }

    regfree(&regular_expression);
}

free (patterns);

由于我不知道的原因,此雷鬼检查将autoRegex status: Match ->^[:digit:]*匹配。我做错了什么?

2 个答案:

答案 0 :(得分:0)

您的代码中有未定义的行为malloc调用以及以下分配不符合您的预期。

malloc调用分配1024(256 * 4)个连续字节,而不是指针数组(类似于char **)。

你不需要在这里动态分配任何东西,只需声明一个指针数组,比如

const char *patterns[] = {
    regular_expression_pattern_keyword,
    regular_expression_pattern_identifier,
    regular_expression_pattern_number,
    regular_expression_pattern_punctuator
};

答案 1 :(得分:0)

这里有几点需要注意:

  • [:digit:]和其他POSIX字符类必须在括号内(&#34;字符&#34;)类(例如[[:digit:]])中使用,而不是单独使用。否则,它们会匹配类中的单独符号,即[:digit:]匹配1个符号,:dig或{{1 }}

  • 要使用替换和非转义括号/括号进行量化/分组,您需要使用t标记REG_EXTENDED来使用ERE正则表达式语法。如果不传递此标志,则表示您使用的是BRE正则表达式语法,这种语法相当差。

现在,为什么regcomp匹配^[:digit:]*?因为您要求正则表达式引擎找到或更多字符,auto:di或{{1} }。它确实在字符串的开头找到零个这样的字符,因此,你有一个匹配。

  

g匹配t,这根本不是一个数字

不,该模式与^[[:digit:]]\{1,\}不匹配,只与1ab中的1ab匹配,因为您尚未指定任何边界或锚点。

要仅匹配字符串开头的数字(=数字序列),请使用

1

不要忘记将1ab标记传递给"^[[:digit:]]+(\\W|$)" (or "^[[:digit:]]+([^[:digit:][:alpha:]_]|$)" 函数。

this demo。请注意,在ERE正则表达式语法中,您可以使用REG_EXTENDED匹配1个或多个字符,而在BRE(不包含regcomp)中,您必须使用+