Используйте GNU libc regexec () для подсчета подстроки - PullRequest
1 голос
/ 11 марта 2009

Можно ли подсчитать, сколько раз подстрока появляется в строке, используя регулярное выражение, сопоставленное с GNU libc regexec ()?

Ответы [ 3 ]

2 голосов
/ 12 марта 2009

Нет, regexec () находит только одно совпадение за вызов. Если вы хотите найти следующее совпадение, вы должны вызвать его еще раз вдоль строки.

Если вы хотите искать только простые подстроки, вам лучше использовать стандартную функцию C string.h strstr () ; тогда вам не придется беспокоиться о экранировании специальных символов регулярных выражений.

0 голосов
/ 27 июня 2014

извините за создание другого ответа, потому что у меня нет 50 репутации. Я не могу комментировать ответ @ Oscar Raig Colon.

pmatch не может соответствовать всем подстрокам, pmatch используется для сохранения смещения для подвыражения, ключ должен понять, что такое подвыражение, подвыражение "\ (\)" в BRE, "()" в ERE. если во всем регулярном выражении нет подвыражения, regexec () возвращает только смещение первой строки совпадения и помещает его в pmatch [0].

Вы можете найти пример на [http://pubs.opengroup.org/onlinepubs/007908799/xsh/regcomp.html][1]

Ниже показано, как флаг REG_NOTBOL можно использовать с regexec (), чтобы найти все подстроки в строке, которые соответствуют шаблону, предоставленному пользователем. (Для простоты примера очень мало проверок на ошибки.)

(void) regcomp (&re, pattern, 0);
/* this call to regexec() finds the first match on the line */
error = regexec (&re, &buffer[0], 1, &pm, 0);
while (error == 0) {    /* while matches found */
    /* substring found between pm.rm_so and pm.rm_eo */
    /* This call to regexec() finds the next match */
    error = regexec (&re, buffer + pm.rm_eo, 1, &pm, REG_NOTBOL);
}
0 голосов
/ 28 ноября 2012

regexec возвращает в своем четвертом параметре "pmatch" структуру со всеми совпадениями. «pmatch» - это структура фиксированного размера, если есть больше совпадений, вы вызовете функцию в другой раз.

Я нашел этот код с двумя вложенными циклами и изменил его. Оригинальная треска, которую вы можете найти в http://www.lemoda.net/c/unix-regex/index.html:

static int match_regex (regex_t * r, const char * to_match)
{
    /* "P" is a pointer into the string which points to the end of the
       previous match. */
    const char * p = to_match;
    /* "N_matches" is the maximum number of matches allowed. */
    const int n_matches = 10;
    /* "M" contains the matches found. */
    regmatch_t m[n_matches];
    int number_of_matches = 0;
    while (1) {
        int i = 0;
        int nomatch = regexec (r, p, n_matches, m, 0);
        if (nomatch) {
            printf ("No more matches.\n");
            return nomatch;
        }
        for (i = 0; i < n_matches; i++) {
            if (m[i].rm_so == -1) {
                break;

            }
            number_of_matches ++;
        }
        p += m[0].rm_eo;
    }
    return number_of_matches ;
}
...