我正在尝试在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(®ular_expression, patterns[i], 0);
if (status)
{
// FIXME: Improve error handling!
printf("Error: Failed to compile regex!\n");
exit(1);
}
status = regexec(®ular_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(®ular_expression);
}
free (patterns);
由于我不知道的原因,此雷鬼检查将auto
与Regex status: Match ->^[:digit:]*
匹配。我做错了什么?
答案 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个符号,:
或d
,i
,g
或{{1 }}
要使用替换和非转义括号/括号进行量化/分组,您需要使用t
标记REG_EXTENDED
来使用ERE正则表达式语法。如果不传递此标志,则表示您使用的是BRE正则表达式语法,这种语法相当差。
现在,为什么regcomp
匹配^[:digit:]*
?因为您要求正则表达式引擎找到零或更多字符,auto
,:
,d
,i
或{{1} }。它确实在字符串的开头找到零个这样的字符,因此,你有一个匹配。
g
匹配t
,这根本不是一个数字
不,该模式与^[[:digit:]]\{1,\}
不匹配,只与1ab
中的1ab
匹配,因为您尚未指定任何边界或锚点。
要仅匹配字符串开头的数字(=数字序列),请使用
1
不要忘记将1ab
标记传递给"^[[:digit:]]+(\\W|$)" (or "^[[:digit:]]+([^[:digit:][:alpha:]_]|$)"
函数。
见this demo。请注意,在ERE正则表达式语法中,您可以使用REG_EXTENDED
匹配1个或多个字符,而在BRE(不包含regcomp
)中,您必须使用+
。