Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中使用正则表达式查找文件中的行?_C_Regex - Fatal编程技术网

如何在C中使用正则表达式查找文件中的行?

如何在C中使用正则表达式查找文件中的行?,c,regex,C,Regex,如何在C编程中使用正则表达式? 例如,如果我想在文件中查找一行 DAEMONS=(sysklogd network sshd !netfs !crond) 然后像这样在单独的行中打印每个守护进程 sysklogd network sshd !netfs !crond 这就是我到目前为止所做的 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/typ

如何在C编程中使用正则表达式? 例如,如果我想在文件中查找一行

DAEMONS=(sysklogd network sshd !netfs !crond)
然后像这样在单独的行中打印每个守护进程

sysklogd 
network 
sshd 
!netfs 
!crond
这就是我到目前为止所做的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define tofind    "[a-z A-Z] $"
int main(){
 FILE *fp;
 char line[1024];
 int retval = 0;
 char address[256];
 regex_t re;

 if(regcomp(&re, tofind, REG_EXTENDED) != 0)
  return;

 fp = fopen("/etc/rc.conf","r");//this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)"
 while((fgets(line, 1024, fp)) != NULL) {
     if((retval = regexec(&re, address, 0, NULL, 0)) == 0)
      printf("%s\n", address);
 } 
}
#包括
#包括
#包括
#包括
#包括
#定义tofind“[a-z a-z]$”
int main(){
文件*fp;
字符行[1024];
int-retval=0;
字符地址[256];
正则表达式;
if(注册表项(&re、tofind、注册表项扩展)!=0)
返回;
fp=fopen(“/etc/rc.conf”,“r”);//此文件有以下行“守护进程=(sysklogd network sshd!netfs!crond)”
while((fgets(第1024行,fp))!=NULL){
if((retval=regexec(&re,address,0,NULL,0))==0)
printf(“%s\n”,地址);
} 
}

任何帮助都将不胜感激。

您将该行读入
,因此您应该将
传递到
regexec()
。您还需要考虑行尾的换行符是否会影响模式。(使用
fgets()
是正确的,但请记住它将换行符保留在末尾。)

您还应该执行
return-1
(或任何其他非0模256的值)而不是无值的普通
返回值。此外,还应检查文件是否已打开;我不得不使用另一个名称,因为在我的机器上没有像/etc/rc.conf这样的文件——MacOS X

这对我很有用:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>

#define tofind    "[a-z A-Z] $"

int main(int argc, char **argv)
{
    FILE *fp;
    char line[1024];
    int retval = 0;
    regex_t re;
    //this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)"
    const char *filename = "/etc/rc.conf";

    if (argc > 1)
        filename = argv[1];

    if (regcomp(&re, tofind, REG_EXTENDED) != 0)
    {
        fprintf(stderr, "Failed to compile regex '%s'\n", tofind);
        return EXIT_FAILURE;
    }

    fp = fopen(filename, "r");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s (%d: %s)\n",
                filename, errno, strerror(errno));
        return EXIT_FAILURE;
    }

    while ((fgets(line, 1024, fp)) != NULL)
    {
        line[strlen(line)-1] = '\0';
        if ((retval = regexec(&re, line, 0, NULL, 0)) == 0)
            printf("<<%s>>\n", line);
    } 
    return EXIT_SUCCESS;
}
只要按图所示写入,这将与该行匹配。如果在“
S
”和“
=
”之间,或者在“
=
”和“
”)之间可以有空格,则需要进行适当的修改。我允许使用尾随空格-人们通常很邋遢;但如果他们使用尾随选项卡,则不会选择该行

一旦找到该行,您就必须将其拆分为多个部分。您可以选择使用“捕获”括号功能,或者简单地使用
strchr()
来查找开放括号,然后使用合适的技术来分离守护程序名称-我会避免使用
strtok()
,可能使用
strspn()
strcspn()
查找单词


#包括
#包括
#包括
#包括
#包括
#包括
#定义tofind“^daemon=\\([^)]*)\\)[\t]*$”
int main(int argc,字符**argv)
{
文件*fp;
字符行[1024];
int-retval=0;
正则表达式;
regmatch_t rm[2];
//此文件有以下行“守护进程=(sysklogd network sshd!netfs!crond)”
const char*filename=“/etc/rc.conf”;
如果(argc>1)
filename=argv[1];
if(注册表项(&re、tofind、注册表项扩展)!=0)
{
fprintf(stderr,“未能编译正则表达式“%s”\n”,tofind);
返回退出失败;
}
fp=fopen(文件名,“r”);
如果(fp==0)
{
fprintf(stderr,“无法打开文件%s(%d:%s)\n)”,文件名,errno,strerror(errno));
返回退出失败;
}
while((fgets(第1024行,fp))!=NULL)
{
行[strlen(行)-1]='\0';
if((retval=regexec(&re,line,2,rm,0))==0)
{
printf(“\n”,第行);
printf(“行:\n”,(int)(rm[0].rm_-eo-rm[0].rm_-so),行+rm[0].rm_-so);
printf(“Text:\n”,(int)(rm[1].rm_eo-rm[1].rm_so),line+rm[1].rm_so);
char*src=line+rm[1].rm_so;
char*end=line+rm[1].rm_eo;
while(srcend)
len=末端-src;
printf(“名称:\n”,(int)len,src);
src+=len;
src+=strspn(src,“”);
}
}
}
返回退出成功;
}
其中包含大量调试代码,但不会花费您很长时间来生成您请求的答案。我得到:

<<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Line: <<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Text: <<sysklogd network sshd !netfs !crond>>
Name: <<sysklogd>>
Name: <<network>>
Name: <<sshd>>
Name: <<!netfs>>
Name: <<!crond>>

行:
正文:
姓名:
姓名:
姓名:
姓名:
姓名:

注意:当你想在正则表达式中使用反斜杠时,你必须在C源代码中写两个反斜杠。

只是想补充一点,正则表达式
toFind
有缺陷。反正什么也配不上。@Jeff:你确定吗?如图所示,RE查找一个字母,后跟一个空格和行尾,或者两个空格和行尾。这对于解析/etc/rc.conf是否合理是一个问题——然而,RE找到了它所说的想要找到的东西?/etc/rc.conf内容是
bla-bla-bla-DAEMONS=(sysklogd-network-sshd!netfs!crond)bla-bla-bla-bla
@Face:OK-那么正则表达式不是您想要的。您需要在问题中显示一个示例行(缩进为代码),并在其下显示希望正则表达式为您找到的部分。正如我在前面的评论中所解释的那样,您输入的正则表达式查找字母字符或空格,然后在行尾加空格。如果这不是你想要的,那么解释一下你是什么。这就形成了你需要的实际正则表达式。@Jonatha:如果我不够清楚的话,很抱歉。我正在尝试将“DAEMONS=(…)”之间的每个单词分开,并以新行打印每个单词。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>

#define tofind    "^DAEMONS=\\(([^)]*)\\)[ \t]*$"

int main(int argc, char **argv)
{
    FILE *fp;
    char line[1024];
    int retval = 0;
    regex_t re;
    regmatch_t rm[2];
    //this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)"
    const char *filename = "/etc/rc.conf";

    if (argc > 1)
        filename = argv[1];

    if (regcomp(&re, tofind, REG_EXTENDED) != 0)
    {
        fprintf(stderr, "Failed to compile regex '%s'\n", tofind);
        return EXIT_FAILURE;
    }

    fp = fopen(filename, "r");
    if (fp == 0)
    {
        fprintf(stderr, "Failed to open file %s (%d: %s)\n", filename, errno, strerror(errno));
        return EXIT_FAILURE;
    }

    while ((fgets(line, 1024, fp)) != NULL)
    {
        line[strlen(line)-1] = '\0';
        if ((retval = regexec(&re, line, 2, rm, 0)) == 0)
        {
            printf("<<%s>>\n", line);
            printf("Line: <<%.*s>>\n", (int)(rm[0].rm_eo - rm[0].rm_so), line + rm[0].rm_so);
            printf("Text: <<%.*s>>\n", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so);
            char *src = line + rm[1].rm_so;
            char *end = line + rm[1].rm_eo;
            while (src < end)
            {
                size_t len = strcspn(src, " ");
                if (src + len > end)
                    len = end - src;
                printf("Name: <<%.*s>>\n", (int)len, src);
                src += len;
                src += strspn(src, " ");
            }
        }
    }
    return EXIT_SUCCESS;
}
<<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Line: <<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Text: <<sysklogd network sshd !netfs !crond>>
Name: <<sysklogd>>
Name: <<network>>
Name: <<sshd>>
Name: <<!netfs>>
Name: <<!crond>>