1

我正在尝试从文件中提取数字。我有限制,我只需要使用open(),read()close().

我已成功读取数据并保存在缓冲区中。不,我需要将其与 RE 匹配。我正在使用 RE = ^[0-9]*

这是我的代码

char buffer[1024] = { NULL };
int count = 0;
int fRead;

fRead = open("file.in", O_RDONLY);
read(fRead, buffer, sizeof(buffer));
printf("\nFile Opened %s, %lu", buffer, sizeof(buffer));

/* Compile regular expression */
regex_t re;
int reti = regcomp(&re, "^[1-9]*", 0);
if (reti) {
    fprintf(stderr, "Could not compile regex\n");
    exit(1);
}

/* Execute regular expression */
reti = regexec(&re, buffer, 0, NULL, 0);
if (!reti) {
    printf("\nMatch: %d", reti);
} else if (reti == REG_NOMATCH) {
    puts("No match");
} else {
    char msgbuf[100];
    regerror(reti, &re, msgbuf, sizeof(msgbuf));
    fprintf(stderr, "Regex match failed: %s\n", msgbuf);
    exit(1);
}
close(fRead);

现在的问题是我想计算并显示我在文件中找到的数字。例如我的文件可能有 text some thing 2 to 3 makes 5,在这种情况下我的输出必须是 OUTPUT: 2,3,5 count = 3

4

1 回答 1

3

查看regexec的手册页。regexec 的返回值是,当您使用它时,0 表示成功或正错误代码。但是,regexec 的其他参数是您如何获取有关匹配项的更多信息。

为方便起见,这里是 regexec 的定义:

int regexec(const regex_t *preg, const char *string, size_t nmatch,
            regmatch_t pmatch[], int eflags);

pmatch 参数是函数在找到匹配项时放置匹配项的位置,nmatch 参数告诉函数 pmatch 参数有多少元素,因此它不会溢出。这类似于其他语言的“匹配”功能,其中 pmatch 的第一个索引将具有完整的正则表达式匹配,而以下索引将具有子组匹配。这意味着您需要使用子组匹配从字符串中获取数字,然后您需要遍历字符串以查找后续子组匹配。

首先,实例化一个 regmatch_t 堆栈变量来保存结果。这只需要大小为 2,因此您可以将完整匹配存储在 0 索引中,将子组匹配存储在 1 索引中。您还需要更改您的正则表达式,以便它匹配整个字符串,直到它得到一个数字。我们将把它连同它的大小一起传递给 regexec 函数以供 nmatch 使用。

每次找到匹配项时,您都需要将字符串的开头向前移动,以便下次调用 regexec 时,您将获得下一个数字,而不是同一个数字。

首先更新正则表达式字符串。

/* if we use .* in the regex it will be greedy and match the last number, not the first.
   We need to use a + instead of a * for the number so we know there is at least 1. */
int reti = regcomp(&re, "[^0-9]*([0-9]+)", REG_EXTENDED);

然后循环查找所有匹配项。

/* regmatch_t is defined in regex.h */
regmatch_t matches[2];
int start;
int end;  

while (1) {
  reti = regexec(&re, buffer, 2, matches, 0);

  /* rm_so is the start index of the match */
  start = matches[1].rm_so;
  /* rm_eo is the end index of the match */
  end = matches[1].rm_eo;
  /* break if we didn't find a match */
  if (reti) break;

  /* print the substring that contains the match */
  printf("%.*s, ", (end - start), (buffer + start));
  /* increment the count of matches */
  count = count + 1;

  /* This is really important!
     Move the start of the string forward so we don't keep matching the same number! */
  buffer = buffer + end;
} 

/* print the count */
printf("count = %d", count);
于 2013-08-02T00:16:28.137 回答