PCRE匹配逗号分隔键值对时C代码仅返回首个匹配项如何解决
问题原因和解决方案
1. 修正待匹配字符串长度参数
你当前pcre_exec的第四个参数写死为7,这代表PCRE只会扫描待匹配字符串的前7个字符,自然不可能匹配到后面的key2相关内容。需要改成实际传入的json字符串的总长度,比如用strlen(json)获取。
2. 开启全局匹配循环
PCRE的单次pcre_exec调用只会返回一次匹配结果,你正则里的g(全局匹配)标志在C接口中不会自动生效,需要手动循环调用pcre_exec,每次将起始偏移量设置为上一次匹配结束的位置(也就是上一次ovector[1]的值),直到pcre_exec返回PCRE_ERROR_NOMATCH为止。
3. 补全正则编译选项
你测试用的正则带m(多行模式)标志,C代码中pcre_compile的第二个参数现在传的是0,需要加上PCRE_MULTILINE才能和测试页的规则一致。
修正后的代码示例
pcre *re; pcre_extra *sd; const char *error; int rc, erroroffset, i; int ovector[OVECCOUNT]; // 编译正则时加上多行模式选项 re = pcre_compile(pattern, PCRE_MULTILINE, &error, &erroroffset, NULL); sd = pcre_study(re, 0, &error); // 存储当前匹配的起始偏移量,初始为0 int start_offset = 0; int json_len = strlen(json); // 取实际待匹配串长度 // 循环匹配直到没有结果 while((rc = pcre_exec(re, sd, json, json_len, start_offset, 0, ovector, OVECCOUNT)) >= 0) { 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); } // 更新下一次匹配的起始位置为当前匹配结束的位置 start_offset = ovector[1]; } pcre_free_study(sd); pcre_free(re); // 记得释放编译好的正则内存
额外注意事项
- 确认
OVECCOUNT的定义值至少为30,足够容纳每次匹配的所有捕获组偏移量(每次匹配最多返回6个分组,对应需要12个ovector元素,30的大小足够) - 如果你的键值对可能包含字母数字以外的字符,需要同步调整正则的匹配规则,避免匹配截断。
内容的提问来源于stack exchange,提问作者Kérdezõsködő Indián
相关产品推荐
相关产品推荐

