2013-08-01 181 views
1

我正在尝试从文件中提取数字。我有限制,我只需要使用open(),read()close()在C中使用regex.h匹配和计算字符串中的任何数字

我已成功读取数据并保存在缓冲区中。不,我需要将它与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); 

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

回答

3

看一看的man page for 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); 
+0

我试过这个,但仍然是我的输出计数为0;为什么这样? 我已将此代码复制并粘贴到我的代码中。 也改变RE,现在RE是[1-9] –

+0

其实它没有进入While循环由于这个 '匹配[pmatch_index] .rm_so!= -1'条件 –

+0

嗯,测试它我也没有进入循环。它看起来像regexec标记完全匹配为0,0(如果你看看匹配[0],你可能会看到rm_so和rm_eo设置为0)。我会试着弄清楚我在这里做错了什么。 – seanmk