簡體   English   中英

使用 pcre_get_substring_list,匹配字符串內的所有模式並使用 PCRE 在 C 中的數組中返回?

[英]Using pcre_get_substring_list, match all pattern inside of string and return in array in C with PCRE?

我需要在 Linux 中使用 C 和 PCRE 來匹配這個字符串“ <test>a</test> <test>b</test> <test>c</Test> ”來獲取字母 a、b 和 Z4A8A0364909D3408B7393 . 我在 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' : %s\n", pattern, errptr);
        exit(1);
    }

    extra = pcre_study(compile, 0, &errptr);
    if ( errptr != NULL ) {
        fprintf(stderr, "ERROR: Could not study '%s' : %s\n", 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 : %s\n", test_str);
        printf("match  :\n");
        for ( int i = 0; match_list[i]; ++ i ) {
            printf("%9s%s\n", " ", 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()
  • 我們不需要 match[],因為pcre_get_substring()調用pcre_malloc()
  • 變量 match_list 必須是char* ,因為我們將它作為&match_list傳遞。
    const char* match_list;
  • function pcre_exec()預計 ovecsize 為 3 的倍數。
    3*(sizeof(ovector)/3)
  • 我將pcre_exec()調用包裝在一個 while 循環中。
  • 我改用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' : %s\n", pattern, errptr);
        exit(1);
    }

    extra = pcre_study(compile, 0, &errptr);
    if ( errptr != NULL ) {
        fprintf(stderr, "ERROR: Could not study '%s' : %s\n", 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("%s\n", match_list);
            pcre_free_substring(match_list);
        }
    }
    if (compile)
        pcre_free(compile);
    if (extra)
        pcre_free(extra);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM