获取C中正则表达式匹配的行

获取C中正则表达式匹配的行,c,regex,numbers,line,C,Regex,Numbers,Line,我写了这段代码,它可以找到在字符串str中找到模式“match”的文件并打印出来 #include <regex.h> #include <string.h> #include <stdio.h> int main(int argc, const char *argv[]) { char *str = strdup("aaaaaaa match aaaaaaaaaaaaaaaaaaaa\n" "bbbbbb

我写了这段代码,它可以找到在字符串str中找到模式“match”的文件并打印出来

#include <regex.h>
#include <string.h>
#include <stdio.h>
int main(int argc, const char *argv[]) {
    char *str = strdup("aaaaaaa match aaaaaaaaaaaaaaaaaaaa\n"
                       "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
                       "cc match ccccccccccccccccccccccccc");
    regex_t regex;
    regmatch_t match;
    regcomp(&regex, "match", REG_EXTENDED);
    while(regexec(&regex, str, 1, &match, 0) != REG_NOMATCH) {
        int beg = match.rm_so;
        int end = match.rm_eo;
        int len = end-beg;
        char *match_string = str+beg;
        match_string[len] = '\0';
        printf("%s\n", match_string);
        str = str + end + 1;
    }
    return 0;
}
#包括
#包括
#包括
int main(int argc,const char*argv[]{
char*str=strdup(“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n”
“bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n”
“cc匹配CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC”);
regex_t regex;
regmatch\u t match;
regcomp(®ex,“匹配”,regu扩展);
while(regexec(®ex,str,1,&match,0)!=REG\u NOMATCH){
int beg=match.rm_so;
int end=match.rm_eo;
int len=结束beg;
char*match_string=str+beg;
匹配字符串[len]='\0';
printf(“%s\n”,匹配字符串);
str=str+end+1;
}
返回0;
}

我的问题是我需要找出比赛在哪一条线上开始。最好是多行匹配,但现在单行就可以了。正则表达式是否有一些隐藏的功能可以用来解决这个问题?

在这段代码中,我将所有匹配项保存到一个链表中,然后遍历字符串以找到匹配项的行。在大多数情况下,它似乎工作得很好。如果有人知道更好的解决方案,请告诉我

#include <regex.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct match_s match_t;

struct match_s {
    int beg;
    match_t *next;
};

int main(int argc, const char *argv[]) {
    char *str = strdup("aaaaaaa match aaaaaaaaaaaaaaaaaaaa\n"
                       "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
                       "cc match ccccccccccccccccccccccccc");
    match_t *head = NULL;      
    match_t *tail = NULL;      
    char *c = str;             
    regex_t regex;             
    regmatch_t match;          
    regcomp(&regex, "match", REG_EXTENDED);
    int prev = 0;
    while(regexec(&regex, str, 1, &match, 0) != REG_NOMATCH) {
        int beg = match.rm_so;
        int end = match.rm_eo;
        str = str + end + 1;
        match_t *match = malloc(sizeof(match_t));
        match->beg = beg + prev;
        match->next = NULL;
        prev += end+1;    
        if(head == NULL) {
            head = match;
            tail = match;
        } else {
            tail->next = match;
            tail = match;
        }
    }
    int line = 0;
    int i = 0;
    for(i = 0; c[i] != '\0' && head != NULL; i++) {
        if(c[i] == '\n') {
            line++;
        } else if(head->beg == i) {
            printf("Match on line: %d\n", line);
            match_t *tmp = head->next;
            free(head);
            head = tmp;
        }
    }
    free(str);
    return 0;
}
#包括
#包括
#包括
#包括
typedef结构匹配;
结构匹配{
int beg;
匹配下一个;
};
int main(int argc,const char*argv[]{
char*str=strdup(“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n”
“bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n”
“cc匹配CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC”);
匹配头=空;
match_t*tail=NULL;
char*c=str;
regex_t regex;
regmatch\u t match;
regcomp(®ex,“匹配”,regu扩展);
int prev=0;
while(regexec(®ex,str,1,&match,0)!=REG\u NOMATCH){
int beg=match.rm_so;
int end=match.rm_eo;
str=str+end+1;
match_t*match=malloc(sizeof(match_t));
匹配->乞讨=乞讨+上一步;
匹配->下一步=空;
上一个+=结束+1;
if(head==NULL){
头=匹配;
尾=匹配;
}否则{
尾部->下一步=匹配;
尾=匹配;
}
}
内线=0;
int i=0;
对于(i=0;c[i]!='\0'&&head!=NULL;i++){
如果(c[i]='\n'){
line++;
}否则如果(头部->beg==i){
printf(“第%d行上的匹配”,第行);
匹配\u t*tmp=head->next;
自由(头);
水头=tmp;
}
}
自由基(str);
返回0;
}

您可以在每次
\n
时使用解析行来拆分字符串

此外,可以使用
struct
存储每一行:

typedef struct {
    char *str;
    size_t lineno;
} line_t;
一旦知道字符串中有多少个
\n
,就可以创建一个结构数组:

line_t *lines = malloc((numlines+1) * sizeof(line_t));
每行的存储方式如下:

Line 1: "aaaaaaa match aaaaaaaaaaaaaaaaaaaa"
Line 2: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
Line 3: "cc match ccccccccccccccccccccccccc";
然后,您只需再次使用
strtok()
检查空格之间的模式。要比较字符串,将很好地使用

下面是一些示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char *str;
    size_t lineno;
} line_t;

int main(void) {
    char str[] = "aaaaaaa match aaaaaaaaaaaaaaaaaaaa\n"
                 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"
                 "cc match ccccccccccccccccccccccccc";
    const char *key = "match";
    const char *delim1 = "\n";
    const char *delim2 = " ";
    char *pattern;
    size_t numlines = 0, count = 0;

    for (size_t i = 0; str[i]; i++) {
        if (str[i] == '\n') {
            numlines++;
        }
    }

    line_t *lines = malloc((numlines+1) * sizeof(line_t));
    if (!lines) {
        printf("Cannot allocate %zu members\n", numlines+1);
        exit(EXIT_FAILURE);
    }

    pattern = strtok(str, delim1);
    while (pattern != NULL) {
        lines[count].str = malloc(strlen(pattern)+1);
        if (!lines[count].str) {
            printf("Cannot allocate %zu bytes\n", strlen(pattern)+1);
            exit(EXIT_FAILURE);
        }
        strcpy(lines[count].str, pattern);
        lines[count].lineno = count+1;
        count++;

        pattern = strtok(NULL, delim1);
    }

    for (size_t i = 0; i < count; i++) {
        pattern = strtok(lines[i].str, delim2);
        while (pattern != NULL) {
            if (strcmp(pattern, key) == 0) {
                printf("pattern '%s' found on line %zu\n", key, lines[i].lineno);
            }
            pattern = strtok(NULL, delim2);
        }
        free(lines[i].str);
        lines[i].str = NULL;
    }

    free(lines);
    lines = NULL;

    return 0;
}
#包括
#包括
#包括
类型定义结构{
char*str;
尺寸线号;
}线路t;
内部主(空){
char str[]=“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
“bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n”
“抄送匹配CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC;
const char*key=“匹配”;
常量字符*delim1=“\n”;
const char*delim2=“”;
字符*模式;
大小=0,计数=0;
对于(大小i=0;str[i];i++){
如果(str[i]='\n'){
numlines++;
}
}
line_t*lines=malloc((numlines+1)*sizeof(line_t));
如果(!行){
printf(“无法分配%zu成员,\n”,numlines+1);
退出(退出失败);
}
模式=strtok(str,delim1);
while(模式!=NULL){
行[count].str=malloc(strlen(模式)+1);
如果(!行[count].str){
printf(“无法分配%zu字节\n”,strlen(模式)+1);
退出(退出失败);
}
strcpy(行[count].str,模式);
行[count]。行号=count+1;
计数++;
模式=strtok(NULL,delim1);
}
对于(大小i=0;i

注意:此代码使用动态内存分配,并在末尾使用指针。如果你想让我解释更多,让我知道

通常您逐行读取并逐行处理,以便跟踪在正则表达式之外执行的行。为什么不使用
strtok()
按新行拆分或使用其他方法拆分字符串?这是一种可能的解决方案,现在考虑一下,我可以保留每个匹配开始的位置列表,然后在每个匹配开始之前迭代str以找到“\n”的数量。为了使其与多行匹配兼容。谢谢您的回答,这在大多数情况下都很有效。我计划让我的程序与#include*模式匹配。我知道有些情况下,程序员会将这些内容扩展到多行。因此,我需要使用多行匹配,如果我将行存储在数组中,可能会变得很棘手。但是我肯定会用到它。@Robert.S是的,我认为他们有很多方法可以做到这一点。我认为它比正则表达式更容易使用。正则表达式有时很难使用。