您将文本读入到
line
中,因此您应该将
line
传递给
regexec()
。您还需要考虑行末的换行符是否会影响模式匹配。(使用
fgets()
是正确的,但请记住它会保留行末的换行符。)
您还应该执行
return -1;
(或任何不是0模256的其他值),而不是一个普通的没有返回值的
return
。此外,您应该检查文件是否已打开;我必须使用替代名称,因为在我的机器上 - MacOS X中没有/etc/rc.conf这样的文件。
以下是适用于我个人情况的代码:
#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;
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;
}
如果您需要帮助编写正则表达式而不是用它们编写C代码的帮助,那么我们需要设计正则表达式以匹配您展示的行。
^DAEMONS=([^)]*) *$
这将匹配与示例相同的行。如果您可以在“
S
”和“
=
”之间或者“
=
”和“
(
”之间有空格,则需要进行适当的修改。我已经允许有尾随空白符 - 人们常常马虎;但是如果他们使用尾随制表符,那么该行将不被选中。
找到该行后,您需要将其分成几部分。您可以选择使用'捕获'括号功能,或者简单地使用
strchr()
查找开放括号,然后使用适当的技术来分离守护程序名称 - 我会避免使用
strtok()
,可能会使用
strspn()
或
strcspn()
来查找单词。
#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];
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>>
注意:当你想在正则表达式中使用反斜杠时,你需要在C源代码中写两个反斜杠。