【问题标题】:Regexp in C - match groupC - 匹配组中的正则表达式
【发布时间】:2011-01-05 13:27:35
【问题描述】:

我一直在努力使用 C 中的正则表达式(只是 /usr/include/regex.h)。


我有(比方说)数百个正则表达式,其中一个可以匹配输入字符串。 目前我正在这样做(实际上是生成它):数百个 do-while 内部匹配,如果不匹配则中断并转到另一个。一个一个:

do {
    if ( regex_match(str, my_regex1) != MY_REGEX_SUCCESS ) DO_FAIL; //break
    ...
    if ( sscanf(str, " %d.%d.%d.%d / %d ", &___ip1, &___ip2, &___ip3, &___ip4, &___pref) != 5 ) DO_FAIL; //break
    ...
} while (0);

do {
    if ( regex_match(str, my_regex2) != MY_REGEX_SUCCESS ) DO_FAIL; //break
    ...
    ...
} while (0);

do {
    if ( regex_match(str, my_regex3) != MY_REGEX_SUCCESS ) DO_FAIL; //break
    ...
    ...
} while (0);

我想要的是这样的:

const char * match1 = "^([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*)$";
const char * match2 = "^([[:space:]]*)(target|origin)([[:space:]]*):([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*):([[:space:]]*)\\*([[:space:]]*)$";
const char * match3 = "^([[:space:]]*)(target|origin)([[:space:]]*):([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*)/([[:space:]]*)(([0-2]?[0-9])|(3[0-2]))([[:space:]]*):([[:space:]]*)(([1-9][0-9]{0,3})|([1-5][0-9]{4})|(6[0-4][0-9]{3})|(65[0-4][0-9]{2})|(655[0-2][0-9])|(6553[0-5]))([[:space:]]*)$";
char * my_match;
asprintf(&my_match, "(%s)|(%s)|(%s)", match1, match2, match3);


int num_gr = give_me_number_of_regex_group(str, my_match)
switch (num_gr) {
    ...
}

并且不知道如何做到这一点......

有什么建议吗?
谢谢!

【问题讨论】:

  • 我认为设计思想有缺陷。为什么你不能在文件中输入字符串,单列。程序有没有一个接一个地读取它们并与字符串一一比较?
  • 另外,如果你只是比较字符串,为什么不使用标准 C 库,特别是:strcmp?

标签: c regex unix posix grouping


【解决方案1】:

我假设您的regex_matchregcompregexec 的某种组合。要启用分组,您需要使用REG_EXTENDED 标志调用regcomp,但不使用REG_NOSUB 标志(在第三个参数中)。

regex_t compiled;
regcomp(&compiled, "(match1)|(match2)|(match3)", REG_EXTENDED);

然后为组分配空间。组数存储在compiled.re_nsub 中。将此号码传递给regexec

size_t ngroups = compiled.re_nsub + 1;
regmatch_t *groups = malloc(ngroups * sizeof(regmatch_t));
regexec(&compiled, str, ngroups, groups, 0);

现在,第一个无效组是在其 rm_sorm_eo 字段中具有 -1 值的组:

size_t nmatched;
for (nmatched = 0; nmatched < ngroups; nmatched++)
    if (groups[nmatched].rm_so == (size_t)(-1))
        break;

nmatched 是匹配的带括号的子表达式(组)的数量。添加您自己的错误检查。

【讨论】:

  • 您好,larsmans,您的假设是正确的,这正是我所需要的,感谢您的建议。 即使子匹配本身包含分组,它也会起作用吗?我已经编辑了底部示例来说明我的问题。再次感谢。
  • @DinGODzilla:我在 Unix RE 标准中找不到对此的任何评论,所以我的猜测是隐式允许递归分组(因为不允许它会使规范和实现复杂化)。请自行尝试递归分组是否有效。
  • 感谢搜索...在哪里可以找到 posix RE 标准? ...找出是否允许“(?:”或其他非捕获分组...
  • 我一直在寻找这个答案!谢谢!
【解决方案2】:

你可以让他们给你一个包含你的正则表达式的字符串数组并测试它们中的每一个。

//count is the number of regexps provided
int give_me_number_of_regex_group(const char *needle,const char** regexps, int count ){
  for(int i = 0; i < count; ++i){
    if(regex_match(needle, regexp[i])){
      return i;
    }
  }
  return -1; //didn't match any
}

还是我在监督什么?

【讨论】:

    【解决方案3】:

    “我有(比方说)数百个正则表达式......”

    您似乎正在尝试比较 IP 地址的四边形部分。一般来说,在使用正则表达式时,在单个目标上使用这么多正则表达式并在匹配后停止时,通常是一个危险信号。

    示例:哪个组将首先正确匹配?
    target ~'American' , pattern ~ /(Ame)|(Ameri)|(American)/
    这甚至不包括子组中的量词。

    如果是常量形式的情况,正则表达式由/来自,例如数据,最好使用 C 的字符串函数将数据从表单中拆分成一个数组,然后将数组项与目标。在这方面,C 比正则表达式快得多。

    【讨论】:

      猜你喜欢
      • 2016-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      相关资源
      最近更新 更多