你已经明白了的意思pmatch
错误地。它不用于获取重复的模式匹配。它用于获取一场比赛的位置及其可能的子组。作为 Linux 手册regcomp(3)
says:
子表达式的偏移量从i
次打开
括号存储在pmatch[i]
。整个正则表达式的匹配地址存储在pmatch[0]
。 (请注意,要返回 N 个子表达式匹配的偏移量,nmatch
必须至少N+1
.)
任何未使用的结构元素都将包含该值-1
.
如果你有正则表达式this (\w+) costs (\d+) USD
,括号内有2个捕获组(\w+)
and (\d+)
;现在如果nmatch
被设置为至少 3,pmatch[0]
将包含整场比赛的开始和结束索引,pmatch[1]
的开始和结束(\w+)
组和pmatch[2]
为了(\d+)
group.
以下代码应打印连续匹配的范围(如果有)(每个范围的开头是第一个字符在匹配范围内,范围的结尾是第一个字符比赛结束后,匹配rm_so
, rm_eo
用法);或字符串"<the input string>" does not contain a match
如果图案never火柴。
它经过精心构造,因此也适用于零长度正则表达式(空正则表达式,或者说正则表达式#?
将在每个字符位置匹配,包括最后一个字符之后;将报告该正则表达式的 28 个匹配项以供输入the cat is in the bathroom.
)
#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>
void match(regex_t *pexp, char *sz) {
// we just need the whole string match in this example
regmatch_t whole_match;
// we store the eflags in a variable, so that we can make
// ^ match the first time, but not for subsequent regexecs
int eflags = 0;
int match = 0;
size_t offset = 0;
size_t length = strlen(sz);
while (regexec(pexp, sz + offset, 1, &whole_match, eflags) == 0) {
// do not let ^ match again.
eflags = REG_NOTBOL;
match = 1;
printf("range %zd - %zd matches\n",
offset + whole_match.rm_so,
offset + whole_match.rm_eo);
// increase the starting offset
offset += whole_match.rm_eo;
// a match can be a zero-length match, we must not fail
// to advance the pointer, or we'd have an infinite loop!
if (whole_match.rm_so == whole_match.rm_eo) {
offset += 1;
}
// break the loop if we've consumed all characters. Note
// that we run once for terminating null, to let
// a zero-length match occur at the end of the string.
if (offset > length) {
break;
}
}
if (! match) {
printf("\"%s\" does not contain a match\n", sz);
}
}
int main(int argc, char* argv[]) {
int rv;
regex_t exp;
rv = regcomp(&exp, "(the)", REG_EXTENDED | REG_ICASE);
if (rv != 0) {
printf("regcomp failed\n");
}
match(&exp, "the cat is in the bathroom.");
regfree(&exp);
return 0;
}
P.S.,正则表达式中的括号(the)
在这种情况下是不必要的;你可以写the
(你最初对在同一位置获得两场比赛的困惑是因为你会获得一场比赛(the)
和一个子匹配the
,如果你没有这些括号,你的代码只会打印第一个匹配的位置一次)。