이것regcomp 및 regexec에 대한 매뉴얼 페이지"사용되지 않은 모든 구조 요소에는 -1 값이 포함됩니다"를 의미합니다.
그러나 마지막 일치 후 값을 확인하는 논리에서는 rm_so
그렇지 않은 것 같습니다. 0과 같습니다:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define MATCH_CNT 4
void print_matches(regmatch_t matches[])
{
printf("Regexec successful.\n");
int i = 0;
for(; i < MATCH_CNT; i++)
{
//########### HERE'S THE RUB ####################
if(matches[i].rm_so != -1)
{
printf("Match %i; Beginning:\t%i\n", i, matches[i].rm_so);
printf("Match %i; End:\t\t%i\n", i, matches[i].rm_eo);
}
}
}
int main(int argc, char *argv[])
{
if(argc != 3)
fprintf(stderr, "retester <pattern> <string>\n");
char *pat = argv[1];
char *str = argv[2];
regex_t compreg;
memset(&compreg, 0, sizeof(regex_t));
regmatch_t matches[MATCH_CNT];
memset(&matches, 0, MATCH_CNT*sizeof(regmatch_t));
int matchcnt = -1;
char *errbuff;
printf("Trying to match with extended regex...\n");
int compret = -2;
//set REG_EXTENDED flag
if((compret = regcomp(&compreg, pat, REG_EXTENDED)) == 0)
{
printf("Compiling successful.\n");
int execret = -2;
if((execret = regexec(&compreg, str, matchcnt, matches, 0)) == 0)
{
print_matches(matches);
}
else if(execret != 0)
{
printf("Regexec failed.\n");
size_t errbuffsz = regerror(execret, &compreg, 0, 0);
errbuff = malloc(errbuffsz);
memset(errbuff, '\0', errbuffsz);
regerror(execret, &compreg, errbuff, errbuffsz);
fprintf(stderr, "Regexec error: %s\n", errbuff);
}
}
else
{
printf("Compiling failed.\n");
size_t errbuffsz = regerror(compret, &compreg, 0, 0);
errbuff = malloc(errbuffsz);
memset(errbuff, '\0', errbuffsz);
regerror(compret, &compreg, errbuff, errbuffsz);
fprintf(stderr, "Regexec error: %s", errbuff);
}
free(errbuff);
errbuff = NULL;
regfree(&compreg);
return 0;
}
이것은 위의 출력입니다. 패턴에 대한 나의 이해는 일치하는 그룹이 하나만 있다는 것입니다. 문서에 따르면 이는 두 개의 패딩 regmatch_t
요소가 표시되어야 함을 의미합니다. 첫 번째 요소는 전체 문자열을 포함하고 두 번째 요소는 일치하는 그룹을 포함합니다.
[chb]$ gcc -g -o foo foo.c
[chb]$ ./foo "^ROOM\s{1}NAME:\s{1}([[:alpha:]]{6})" "ROOM NAME: BriCol"
Trying to match with extended regex...
Compiling successful.
Regexec successful.
Match 0; Beginning: 0
Match 0; End: 17
Match 1; Beginning: 11
Match 1; End: 17
Match 2; Beginning: 0
Match 2; End: 0
Match 3; Beginning: 0
Match 3; End: 0
나는 심지어 명령 내부의 논리가 어떤 식으로든 영향을 받았다고 memset
생각하면서 배열의 제로화를 주석 처리했습니다 .regexec
답변1
사용하지 않는 배열 요소를 -1로 채우 려면 regexec
먼저 거기에 몇 개가 있는지 알려 주어야 합니다. 이 줄을 matchcnt
다음으로 바꾸세요.MATCH_CNT
if((execret = regexec(&compreg, str, matchcnt, matches, 0)) == 0)
그래서 그것은된다
if((execret = regexec(&compreg, str, MATCH_CNT, matches, 0)) == 0)
int
(그리고 이전에 누락된 것을 추가하면 compret = -2;
) 프로그램이 예상대로 작동할 것입니다.
$ ./549805 "^ROOM\s{1}NAME:\s{1}([[:alpha:]]{6})" "ROOM NAME: BriCol"
Trying to match with extended regex...
Compiling successful.
Regexec successful.
Match 0; Beginning: 0
Match 0; End: 17
Match 1; Beginning: 11
Match 1; End: 17
$
또한 정의되지 않은 값으로 호출하는 것을 방지하려면 ( 초기화되지 않은 경우) errbuff
로 초기화해야 합니다 . 이렇게 하면 반환 값을 확인하세요 - 할당NULL
free()
errbuff
malloc()
할 수 있는실패하다.