使用pcre_get_substring_list,匹配字符串内部的所有模式,并使用pcre在C中的数组中返回



我需要在Linux中使用C和PCRE来匹配这个字符串"CCD_ 1";得到字母a、b和c。我在stackoverflow中找到了这个脚本,它很好,但并不适用于所有比赛。只有第一场比赛。为什么?

/*
*   gcc pcre1.c -lpcre   
*/     
#include <pcre.h>
#include <stdio.h>
#include <string.h>
int main()
{
pcre*        compile;
pcre_extra*  extra;;
int          res;
int          ovector[30];
const char* pattern="(?i)<test>(.*?)</test>";
const char*  errptr;
const char*  match[30];
const char** match_list = match;
int          erroffset;
char*        test_str = "<test>a</test> <test>b</test> <test>c</Test>";
compile = pcre_compile(pattern, PCRE_MULTILINE,&errptr,&erroffset,NULL);
if ( compile == NULL ) {
fprintf(stderr, "ERROR: Could not compile '%s' : %sn", pattern, errptr);
exit(1);
}
extra = pcre_study(compile, 0, &errptr);
if ( errptr != NULL ) {
fprintf(stderr, "ERROR: Could not study '%s' : %sn", pattern, errptr);
exit(1);
}
res = pcre_exec(compile,extra,test_str,strlen(test_str),0,0,ovector,sizeof(ovector));
if ( res == 0 ) {
res = 30/3;
}
if ( res > 0 ) {
pcre_get_substring_list(test_str, ovector, res, &match_list);
printf("buffer : %sn", test_str);
printf("match  :n");
for ( int i = 0; match_list[i]; ++ i ) {
printf("%9s%sn", " ", match_list[i]);
printf("n");
}
if ( match_list )
pcre_free_substring_list(match_list);
}
printf("n");
if (compile)
pcre_free(compile);
if (extra)
pcre_free(extra);
}```
thanks

我稍微更改了您的代码,但现在正如您所期望的那样:

% ./pcre1
a
b
c

我将列出更改以及为什么进行更改:

  • 在最初设置ovector之前,我们将使用它,因此清零
    int ovector[30] = {0};
  • pcre_get_substring()将更容易用于此目的,所以我放弃了pcre_get_substring_list()
  • 我们不需要匹配[],因为pcre_get_substring()调用pcre_malloc()
  • 变量match_list必须是char*,因为我们将其作为&match_list传递
    <test>a</test> <test>b</test> <test>c</Test>0
  • 函数pcre_exec()期望ovecsize为3的倍数。
    3*(sizeof(ovector)/3)
  • 我在while循环中结束了pcre_exec()调用
  • 我使用了pcre_get_substring()printf()pcre_free_substring()
//   gcc pcre1.c -lpcre
#include <pcre.h>
#include <stdio.h>
#include <string.h>
int main()
{
pcre*        compile;
pcre_extra*  extra;;
int          res;
int          ovector[30] = {0};
const char*  pattern="(?i)<test>(.*?)</test>";
const char*  errptr;
const char*  match_list;
int          erroffset;
char*        test_str = "<test>a</test> <test>b</test> <test>c</Test>";
compile = pcre_compile(pattern, PCRE_MULTILINE,&errptr,&erroffset,NULL);
if ( compile == NULL ) {
fprintf(stderr, "ERROR: Could not compile '%s' : %sn", pattern, errptr);
exit(1);
}
extra = pcre_study(compile, 0, &errptr);
if ( errptr != NULL ) {
fprintf(stderr, "ERROR: Could not study '%s' : %sn", pattern, errptr);
exit(1);
}
while ((res = pcre_exec(compile, extra, test_str, strlen(test_str), ovector[1], 0, ovector, 3*(sizeof(ovector)/3))) >= 0) {
if (pcre_get_substring(test_str, ovector, res, 1, &match_list) >= 0) {
printf("%sn", match_list);
pcre_free_substring(match_list);
}
}
if (compile)
pcre_free(compile);
if (extra)
pcre_free(extra);
}

最新更新