正则表达式不适用于C语言

时间:2016-08-09 10:00:48

标签: regex posix

我在shell上使用它时正在使用正则表达式,但它不适用于C程序。

有什么想法吗?

echo "abc:1234567890@werty.wer.sdfg.net" | grep -E "(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)"   //shell

reti = regcomp(&regex,"(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)", 0); //c program

2 个答案:

答案 0 :(得分:4)

grep -E使用了一些增强的ERE语法,这意味着{n,m}量词括号(以及())不必转义(在BRE中不是这种情况)正则表达式)。

您需要将REG_EXTENDED标记传递给regcomp,并且由于您无法使用字边界,因此请将第一个\b替换为(^|[^[:alnum:]_])“ ”。您不需要跟踪\b,因为后面的模式中有:

const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";

(^|[^[:alnum:]_])部分匹配字符串的开头(^)或(|)除字母数字或下划线以外的字符。

完整C demo

#include <stdio.h>
#include <stdlib.h>
#include <regex.h>

int main (void)
{
  int match;
  int err;
  regex_t preg;
  regmatch_t pmatch[4];
  size_t nmatch = 4;
  const char *str_request = "abc:1234567890@werty.wer.sdfg.net";

  const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
  err = regcomp(&preg, str_regex, REG_EXTENDED);
  if (err == 0)
    {
      match = regexec(&preg, str_request, nmatch, pmatch, 0);
      nmatch = preg.re_nsub;
      regfree(&preg);
      if (match == 0)
        {
          printf("\"%.*s\"\n", pmatch[2].rm_eo - pmatch[2].rm_so, &str_request[pmatch[2].rm_so]);
          printf("\"%.*s\"\n", pmatch[3].rm_eo - pmatch[3].rm_so, &str_request[pmatch[3].rm_so]);
        }
      else if (match == REG_NOMATCH)
        {
          printf("unmatch\n");
        }
    }
  return 0;
 }

答案 1 :(得分:1)

Word边界参考

General
POSIX

从上面的链接看来POSIX支持它自己的单词边界结构 请注意,这些结构[[:<:]][[:>:]]不是类。

考虑到这一点,使用ERE而不是BRE,你应该能够做到这一点 -

reti = regcomp(&regex,"[[:<:]](abc|def)[[:>:]]:[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);

或者,因为[cf]:之间是一个自然的单词边界,所以它可以简化为

reti = regcomp(&regex,"[[:<:]](abc|def):[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);

我没有测试过这个,但它可能有效 鉴于它实际上不清楚内部的内容,它可能更好 坚持这种语法。

某些引擎(如 Boost 具有POSIX选项)会将语法自定义为\<\>