Как вы захватываете группу с регулярным выражением?
Я пытаюсь извлечь строку из другого с помощью regex.
Я использую функции регулярного выражения POSIX (regcomp, regexec
...), и я не могу захватить группу...
Например, пусть шаблон будет таким простым, как "MAIL FROM:<(.*)>"
(с REG_EXTENDED
cflags)
Я хочу захватить все между '<' и ' > '
Моя проблема в том, что regmatch_t
дает мне границы всего шаблона (MAIL FROM: <... > ) вместо того, что между скобками...
Что мне не хватает?
Спасибо заранее,
изменить: код
#define SENDER_REGEX "MAIL FROM:<(.*)>"
int main(int ac, char **av)
{
regex_t regex;
int status;
regmatch_t pmatch[1];
if (regcomp(®ex, SENDER_REGEX, REG_ICASE|REG_EXTENDED) != 0)
printf("regcomp error\n");
status = regexec(®ex, av[1], 1, pmatch, 0);
regfree(®ex);
if (!status)
printf( "matched from %d (%c) to %d (%c)\n"
, pmatch[0].rm_so
, av[1][pmatch[0].rm_so]
, pmatch[0].rm_eo
, av[1][pmatch[0].rm_eo]
);
return (0);
}
<сильные > выходы:
$./a.out "012345MAIL FROM:<abcd>$"
matched from 6 (M) to 22 ($)
Решение:
как сказал RarrRarrRarr, индексы действительно находятся в pmatch[1].rm_so
и pmatch[1].rm_eo
следовательно, regmatch_t pmatch[1];
становится regmatch_t pmatch[2];
и regexec(®ex, av[1], 1, pmatch, 0);
становится regexec(®ex, av[1], 2, pmatch, 0);
Спасибо:)
Ответы
Ответ 1
0-й элемент массива pmatch структур regmatch_t будет содержать границы всей строки, сопоставленной, как вы заметили. В вашем примере вас интересует regmatch_t по индексу 1, а не по индексу 0, чтобы получить информацию о совпадении строк по подвыражению.
Если вам нужна дополнительная помощь, попробуйте отредактировать свой вопрос, чтобы включить образец небольшого кода, чтобы люди могли легче определить проблему.
Ответ 2
Вот пример кода, демонстрирующий захват нескольких групп.
Вы можете видеть, что группа "0" - это полное совпадение, а последующие группы - это части в круглых скобках.
Обратите внимание, что это только фиксирует первое совпадение в исходной строке. Здесь версия, которая захватывает несколько групп в нескольких совпадениях.
#include <stdio.h>
#include <string.h>
#include <regex.h>
int main ()
{
char * source = "___ abc123def ___ ghi456 ___";
char * regexString = "[a-z]*([0-9]+)([a-z]*)";
size_t maxGroups = 3;
regex_t regexCompiled;
regmatch_t groupArray[maxGroups];
if (regcomp(®exCompiled, regexString, REG_EXTENDED))
{
printf("Could not compile regular expression.\n");
return 1;
};
if (regexec(®exCompiled, source, maxGroups, groupArray, 0) == 0)
{
unsigned int g = 0;
for (g = 0; g < maxGroups; g++)
{
if (groupArray[g].rm_so == (size_t)-1)
break; // No more groups
char sourceCopy[strlen(source) + 1];
strcpy(sourceCopy, source);
sourceCopy[groupArray[g].rm_eo] = 0;
printf("Group %u: [%2u-%2u]: %s\n",
g, groupArray[g].rm_so, groupArray[g].rm_eo,
sourceCopy + groupArray[g].rm_so);
}
}
regfree(®exCompiled);
return 0;
}
Вывод:
Group 0: [ 4-13]: abc123def
Group 1: [ 7-10]: 123
Group 2: [10-13]: def