gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 01:24:33 24 4
gpt4 key购买 nike

我在 C 语言中使用 POSIX 正则表达式 regex.h 来计算一个短语在英语文本片段中出现的次数。但是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;
}

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

最佳答案

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

The offsets of the subexpression starting at the ith open parenthesis are stored in pmatch[i]. The entire regular expression's match addresses are stored in pmatch[0]. (Note that to return the offsets of N subexpression matches, nmatch must be at least N+1.) Any unused structure elements will contain the value -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;
}

附言,正则表达式中的括号 (the)在这种情况下是不必要的;你可以写the (并且您最初对在同一位置获得 2 个匹配项感到困惑是因为您将获得一个匹配项 (the) 和一个子匹配项 the,如果您没有这些括号,您的代码将打印第一个匹配项的位置只有一次)。

关于在 C 中使用 regex.h 计算匹配数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36975020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com