【问题标题】:regexp with pcre in C how match all pattern?C中带有pcre的正则表达式如何匹配所有模式?
【发布时间】:2021-12-28 17:44:53
【问题描述】:

我已经在 linux 中使用 PCRE 在 C 中创建了一个脚本,用于匹配字符串中的一个单词,它可以工作,但现在我想修改它,因为我希望它匹配,短语中的所有相同单词,我这样做这个模组。但返回给我警告:从不兼容的指针类型 [-Wincompatible-pointer-types] 传递“pcre_get_substring”的参数 2 ,对不起,我是 C 的初学者程序员,谁能给我一个解释的解决方案?谢谢

*   gcc -Wall pcre1.c -I/usr/local/include -L/usr/local/lib -R/usr/local/lib -lpcre
*   or
*   gcc -Wall pcre1.c -I/usr/local/include -L/usr/local/lib  -lpcre   
*   or
*   gcc pcre1.c -lpcre   
*/     
#include <stdio.h>
#include <string.h>
#include <pcre.h>               
#define OVECCOUNT 30    /* should be a multiple of 3 */
#define EBUFLEN 128            
#define BUFLEN 1024           
        
int main()
{               
        pcre *re;
        const char *error;
        int erroffset;
        int ovector[OVECCOUNT];
        int rc, i;
int offsetcount;
int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
char *result;
        char src[] = "111 <title>Hello World</title> <title>Hello World</title>222";
        char pattern[] = "<title>(.*)</title>";
        re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
        if (re == NULL) {
                printf("PCRE compilation failed at offset %d: %s/n", erroffset, error);
                return 1;
        }
offsetcount = pcre_exec(re, NULL, src, strlen(src), 0, 0, offsets, (0+1)*3);
    while (offsetcount > 0) {
        if (pcre_get_substring(src, &offsets, offsetcount, 0, &result) >= 0) {
            // Do something with match we just stored into result
            printf("de %s/n",result);
        }
        offsetcount = pcre_exec(re, NULL, src, strlen(src), 0, offsets[1], offsets, (0+1)*3);
    } 
        free(re);
        return 0;
}```

【问题讨论】:

  • &amp;offsets 应该只是offsets,因为offsets 已经是一个指针/数组。
  • 我删除 &offsets 到 -> 偏移和 &result -> 结果,因为给我同样的错误,但现在告诉我警告:从不兼容的指针类型传递 'pcre_get_substring' 的参数 5 [-Wincompatible-pointer-types ] 63 | if (pcre_get_substring(src, offsets, offsetcount, 0, result) >= 0) { | ^~~~~~ | | |字符 *
  • (const char **) &amp;result
  • 谢谢它的工作,我也有一些问题,再次抱歉,1.(const char **) &result 是指针的演员?我明白好吗? 2. 如果我想要打印结果,我插入``` if (pcre_get_substring(src, offsets, offsetcount, 0, (const char **) &result) >= 0) { printf("de %s/n", &result); }``` 但返回错误“%s”需要“char *”类型的参数,但参数 2 的类型为“const char **”
  • 是的,这是一个演员表。 pcre_get_substring 的第 5 个参数的类型必须是 const char **。只需将resultprintf 一起使用,而不是&amp;result。如果您想查看打印的内容,请将模式更改为 "&lt;title&gt;.*&lt;/title&gt;",因为您的代码不会按原样打印捕获组内容。

标签: c regex pcre


【解决方案1】:

例如:

#include <pcre.h>
#include <stdio.h>
#include <string.h>
          
#define OFFSETCOUNT 6    // (capturing_group_count + 1) * 3
          
int main() {
    const char *error;
    int erroffset;
    int offsetcount;
    int offsets[OFFSETCOUNT];
    const char *result;

    char src[] = "<title>One</title> <title>Two</title> <title>Three</title> <title>Four</title> <title>Five</title>";
    char pattern[] = "<title>(.*?)</title>";

    pcre *re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
    if (re == NULL) {
        printf("PCRE compilation failed at offset %d: %s/n", erroffset, error);
        return 1;
    }

    offsets[1] = 0;
    while ((offsetcount = pcre_exec(re, NULL, src, strlen(src), offsets[1], 0, offsets, OFFSETCOUNT)) >= 0) { 
        if (pcre_get_substring(src, offsets, offsetcount, 1, &result) >= 0) {
            printf("%s\n", result);
            pcre_free_substring(result);
        }
    } 
    
    free(re);
    return 0;
}

打印:

One
Two
Three
Four
Five

除了类型错误之外,您的代码的主要问题是使用(0+1)*3 而不是OVECCOUNT 或至少6,因为您正在使用带有一个捕获组的正则表达式。

您还需要在您的正则表达式中添加一个? 以使.* 匹配“懒惰”,即尽可能少地匹配,否则.* 将贪婪地从"&lt;title&gt;" 匹配到最后一个@987654330 @。

此外,您将0 传递给获得完整匹配的pcre_get_substring,而不是获得第一个捕获组匹配的1

【讨论】:

  • 无限感谢@MikeM
  • 但为了获得更好的结果(我在 PCRE 的帮助下阅读)对于我的情况有一个匹配列表,我应该使用 pcre_get_substring_list ?快得多?谢谢
  • @RubensBarrichello77 pcre_get_substring_list 不会更快。它不会给出所有匹配项,它只是生成一个由单个 pcre_exec 调用匹配的子字符串列表。如果在上面的示例中使用,每次调用它时只会生成一个包含两个项目的列表:完整匹配和单个捕获组匹配。如果需要所有匹配项,pcre_exec 仍然必须像上面那样重复调用。顺便说一句,您真的应该使用 PCRE2,因为 PCRE 现在“生命终结”。
  • 感谢您的回复和美好的一年,好的,我明白了,使用 pcre2 我更改包括?你的脚本(例如)的其余部分是否相同?还是完全不同?再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多