使用C中的regex.h计算匹配数

huy*_*yen 2 c regex

regex.h在C中使用POSIX正则表达式来计算英语文本片段中短语的出现次数.但返回值regexec(...)仅表示是否找到匹配项.所以我尝试使用nmatchmatchptr找到不同的外观,但是当我打印出匹配时matchptr,我刚收到第一个短语的第一个索引出现在我的文本中.

这是我的代码:

#include <sys/types.h>
#include <regex.h>
#include <stdio.h>

#define MAX_MATCHES 20 //The maximum number of matches allowed in a single string

void match(regex_t *pexp, char *sz) {
    regmatch_t matches[MAX_MATCHES];
    if (regexec(pexp, sz, MAX_MATCHES, matches, 0) == 0) {
    for(int i = 0; i < MAX_MATCHES; i++)
        printf("\"%s\" matches characters %d - %d\n", sz, matches[i].rm_so, matches[i].rm_eo);
    } 
    else {
        printf("\"%s\" does not match\n", sz);
    }
}

int main(int argc, char* argv[]) {
    int rv;
    regex_t exp;
    rv = regcomp(&exp, "(the)", REG_EXTENDED | REG_ICASE);
    if (rv != 0) {
        printf("regcomp failed\n");
    }
    match(&exp, "the cat is in the bathroom.");
    regfree(&exp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何使此代码报告(the)字符串中正则表达式的两个不同匹配the cat is in the bathroom

Ant*_*ala 5

你已经理解了pmatch错误的含义.它不用于获取重复的模式匹配.它用于获取一个匹配的位置及其可能的子组.正如Linux手册regcomp(3)所说:

从第i个左括号开始的子表达式的偏移量存储在pmatch [i]中.整个正则表达式的匹配地址存储在pmatch [0]中.(注意,要返回N个子表达式匹配的偏移量,nmatch必须至少为N + 1.)任何未使用的结构元素都将包含值-1.

如果你有正则表达式this (\w+) costs (\d+) USD,有括号2个捕获组(\w+)(\d+); 现在如果nmatch设置为至少3,pmatch[0]将包含整场比赛的起点和终点指标,pmatch[1]开始和结束的 (\w+)小组,并pmatch[2](\d+)组.


以下代码应打印连续匹配的范围(如果有),或者"<the input string>" does not contain a match如果模式从不匹配则打印字符串.

它是精心构造的,因此它也适用于零长度正则表达式(空正则表达式,或者说正则表达式#?将匹配每个字符位置,包括在最后一个字符之后;将报告该正则表达式的28个匹配项用于输入the cat is in the bathroom.)

#include <sys/types.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>


void match(regex_t *pexp, char *sz) {
    // we just need the whole string match in this example    
    regmatch_t whole_match;

    // we store the eflags in a variable, so that we can make
    // ^ match the first time, but not for subsequent regexecs
    int eflags = 0;
    int match = 0;
    size_t offset = 0;
    size_t length = strlen(sz);

    while (regexec(pexp, sz + offset, 1, &whole_match, eflags) == 0) {
        // do not let ^ match again.
        eflags = REG_NOTBOL;
        match = 1;
        printf("range %zd - %zd matches\n",
               offset + whole_match.rm_so,
               offset + whole_match.rm_eo);

        // increase the starting offset
        offset += whole_match.rm_eo;

        // a match can be a zero-length match, we must not fail
        // to advance the pointer, or we'd have an infinite loop!
        if (whole_match.rm_so == whole_match.rm_eo) {
            offset += 1;
        }

        // break the loop if we've consumed all characters. Note
        // that we run once for terminating null, to let
        // a zero-length match occur at the end of the string.
        if (offset > length) {
            break;
        }
    }
    if (! match) {
        printf("\"%s\" does not contain a match\n", sz);
    }
}


int main(int argc, char* argv[]) {
    int rv;
    regex_t exp;
    rv = regcomp(&exp, "(the)", REG_EXTENDED | REG_ICASE);
    if (rv != 0) {
        printf("regcomp failed\n");
    }
    match(&exp, "the cat is in the bathroom.");
    regfree(&exp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

PS,你的正则表达式(the)中的括号在这种情况下是不必要的; 你可以写the一下(你最初在同一位置得到2场比赛的混乱是因为你得到一场比赛(the)和一场比赛the,如果你没有这些括号,你的代码只会打印第一场比赛的位置一次).