是否可以使用与 GNU libc regexec() 匹配的正则表达式来计算子字符串在字符串中出现的次数?
3 回答
不, regexec() 每次调用只能找到一个匹配项。如果你想找到下一个匹配,你必须沿着字符串再次调用它。
如果您只想搜索普通子字符串,最好使用标准 C string.h 函数strstr();那么您不必担心转义特殊的正则表达式字符。
regexec 在其第四个参数“pmatch”中返回一个包含所有匹配项的结构。“pmatch”是一个固定大小的结构,如果有更多匹配,您将再次调用该函数。
我发现这段代码有两个嵌套循环,我已经修改了它。您可以在http://www.lemoda.net/c/unix-regex/index.html中找到原始鳕鱼:
static int match_regex (regex_t * r, const char * to_match)
{
/* "P" is a pointer into the string which points to the end of the
previous match. */
const char * p = to_match;
/* "N_matches" is the maximum number of matches allowed. */
const int n_matches = 10;
/* "M" contains the matches found. */
regmatch_t m[n_matches];
int number_of_matches = 0;
while (1) {
int i = 0;
int nomatch = regexec (r, p, n_matches, m, 0);
if (nomatch) {
printf ("No more matches.\n");
return nomatch;
}
for (i = 0; i < n_matches; i++) {
if (m[i].rm_so == -1) {
break;
}
number_of_matches ++;
}
p += m[0].rm_eo;
}
return number_of_matches ;
}
很抱歉创建另一个答案,因为我没有 50 声望。我无法评论@Oscar Raig Colon 的回答。
pmatch 不能匹配所有的子字符串,pmatch 是用来保存子表达式的偏移量,关键是要明白什么是子表达式,子表达式在 BRE 中是“\(\)”,在 ERE 中是“()”。如果整个正则表达式中没有子表达式,regexec() 只返回第一个匹配字符串的偏移量并将其放入pmatch[0]。
您可以在 [ http://pubs.opengroup.org/onlinepubs/007908799/xsh/regcomp.html][1]找到一个示例
下面演示了 REG_NOTBOL 标志如何与 regexec() 一起使用来查找行中与用户提供的模式匹配的所有子字符串。(为简单起见,很少进行错误检查。)
(void) regcomp (&re, pattern, 0);
/* this call to regexec() finds the first match on the line */
error = regexec (&re, &buffer[0], 1, &pm, 0);
while (error == 0) { /* while matches found */
/* substring found between pm.rm_so and pm.rm_eo */
/* This call to regexec() finds the next match */
error = regexec (&re, buffer + pm.rm_eo, 1, &pm, REG_NOTBOL);
}