match[0]
относится к той части текста, которая соответствует всему шаблону. match[1]
- это совпадение, соответствующее первому захвату (заключенный в скобки подшаблон).
Обратите внимание, что &s[match[1].rm_so]
дает вам указатель на начало захвата, но если вы напечатаете строку в этой точке, вы будете получить часть строки, начиная с начала захвата. В этом случае это не имеет значения. Поскольку вы используете sscanf
для извлечения целочисленного значения захваченного текста, тот факт, что подстрока не завершается сразу, не имеет значения; за ним не будет следовать ди git, и sscanf
остановится на первом не-ди git.
Но в общем случае возможно, что это будет не так просто чтобы определить конец сопоставленного захвата, и вы можете использовать один из следующих методов:
Если вы хотите напечатать захват, вы можете использовать формат вычисленной ширины строки: (См. Примечание 1.)
printf("%.*s\n", match[1].rm_eo - match[1].rm_so, &s[match[1].rm_so]);
Если у вас есть strndup
, вы можете легко создать динамически распределяемую копию захвата: (См. Примечание 2.)
char* capture = strndup(&s[match[1].rm_so], match[1].rm_eo - match[1].rm_so);
Как быстрый и грязный хак, также можно просто вставить терминатор NUL (при условии, что искомая строка не является неизменной, что означает, что она не может быть строковым литералом). Возможно, вы захотите сохранить старое значение следующего символа, чтобы вы могли восстановить строку в ее первоначальное состояние:
char* capture = &s[match[1].rm_so];
char* rest = &s[match[1].rm_eo];
char saved_char = *rest;
*rest = 0;
/* capture now points to a NUL-terminated string. */
/* ... */
/* restore s */
*rest = saved_char;
Ничто из вышеперечисленного не является действительно необходимым в контексте исходного вопроса, так как sscanf
, как написано, будет отлично работать, если вы измените начало строки для сканирования с match[0]
на match[1]
.
Примечания:
In В общем случае вы должны проверить, чтобы убедиться, что захват действительно был найден, прежде чем пытаться использовать его смещение. Член rm_so
будет равен -1, если перехват не был найден во время поиска по регулярному выражению. Это не обязательно означает, что поиск не удался, потому что перехват может быть частью альтернативы, не используемой в совпадении.
Не забудьте освободить копию, когда она вам больше не нужна. Если у вас нет strndup
, это довольно легко реализовать. Но остерегайтесь угловых случаев.