使用 PCRE 进行全局匹配

Global matching using PCRE

我尝试使用 PCRE 匹配以逗号分隔的键值对。文本如下所示:

"key1": "value1", "key2": "value2"

测试模式为:

/(\s*)(,?)"([a-zA-Z0-9]+?)":(\s*)"([a-zA-Z0-9]+?)"/gm

可以测试正则表达式here:

它在这个测试页中有效,但使用这个 C 代码它只显示第一个匹配组。

pcre *re;
pcre_extra *sd;
const char *error;
int rc, erroroffset, i;
int ovector[OVECCOUNT];
re = pcre_compile(pattern, 0, &error, &erroroffset, NULL);
sd = pcre_study(
    re,             /* result of pcre_compile() */
    0,              /* no options */
    &error);        /* set to NULL or points to a message */
rc = pcre_exec(   /* see below for details of pcre_exec() options */
    re, sd, json, 7, 0, 0, ovector, 30);
pcre_free_study(sd);
printf("Match succeeded at offset %d\n", ovector[0]);
for (i = 0; i < rc; i++) {
    char *substring_start = json + ovector[2*i];
    int substring_length = ovector[2*i+1] - ovector[2*i];
    printf("%2d: '%.*s'\n", i, substring_length, substring_start);
}

结果是

Match succeeded at offset 1
 0: '"key1": "value1"'
 1: ''
 2: ''
 3: 'key1'
 4: ' '
 5: 'value1'

但我需要所有匹配的组,

'key2'
'value2'

执行一次pcre_exec()将捕获一个键值对。您必须重复 pcre_exec() 才能获得额外的键值对。显然,在第二次迭代中,您需要从字符串中的不同位置开始——最后一个匹配字符的偏移量可用 ovector[1],因此您将捕获它并使用:

size_t offset = 0;

while ((rc = pcre_exec(…, json + offset, …)) == 0)
{
    …
    offset += ovector[1];
}

您还可以调查 pcre_dfa_exec()

我想知道为什么您将(可选的)前导白色 space 和逗号作为单独的项目捕获 - 这些信息有用吗?当然,这取决于您的要求。