我试图在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:]";

要检查reggae,我有一个函数:
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);

由于我不知道的原因,这个reggae检查将auto匹配为Regex status: Match ->^[:digit:]*我做错什么了?

最佳答案

这里有几点需要注意:
[:digit:]和其他POSIX字符类必须在括号中的(“字符”)类(例如[[:digit:]])中使用,而不是单独使用否则,它们与类中的单独符号匹配,即[:digit:]与1个符号匹配,要么:,要么digt
要使用交替和无转义的方括号/圆括号进行量化/分组,需要使用REG_EXTENDED标志和regcomp来使用ERE regex语法如果不传递此标志,则使用BRE regex语法,这相当糟糕。
现在,为什么^[:digit:]*匹配auto因为您要求regex引擎查找零个或多个字符,可以是:digt它确实在字符串的开头找到了零个这样的字符,因此,您有一个匹配项。
^[[:digit:]]\{1,\}匹配1ab这根本不是数字
不,模式不匹配1ab,它只匹配1中的1ab,因为您没有指定任何边界或定位。
要只匹配字符串开头的数字(=数字序列),请使用

"^[[:digit:]]+(\\W|$)" (or "^[[:digit:]]+([^[:digit:][:alpha:]_]|$)"

不要忘记将REG_EXTENDED标志传递给regcomp函数。
this demo注意,在ERE regex语法中,可以使用+来匹配1个或多个字符,而在BRE(不带REG_EXTENDED)中,则必须使用\{1,\}

关于c - C POSIX正则表达式失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34117450/

10-11 19:45