【问题标题】:posix regular expression for parsing uevent causing error用于解析uevent导致错误的posix正则表达式
【发布时间】:2017-11-30 01:13:11
【问题描述】:

我正在尝试使用以下代码解析 uevent,但我认为我的正则表达式不正确导致 regcomp 函数失败。

有人可以帮忙吗?我正在尝试做类似this 的事情。

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

int main ()
{
  char * source = "change@/devices/soc/799999.i2c/i2c-3/3-0015/power_supply/battery";
  char * regexString = "(?<action>[a-zA-Z]+)@\\/(?<dev_path>.*)\\/(?<subsystem>[a-zA-z]+)\\/(?<name>[a-zA-z]+)";
  size_t maxGroups = 4;

  regex_t regexCompiled;
  regmatch_t groupArray[maxGroups];

  if (regcomp(&regexCompiled, regexString, REG_EXTENDED))
    {
      printf("Could not compile regular expression.\n");
      return 1;
    };
  regfree(&regexCompiled);

  return 0; 
}

我收到“无法编译正则表达式。”。这意味着 regcomp 无法识别该正则表达式。

【问题讨论】:

    标签: c regex posix-ere


    【解决方案1】:

    当我使用代码报告错误时:

    #include <stdio.h>
    #include <string.h>
    #include <regex.h>
    
    int main(void)
    {
      //char * source = "change@/devices/soc/799999.i2c/i2c-3/3-0015/power_supply/battery";
      char * regexString = "(?<action>[a-zA-Z]+)@\\/(?<dev_path>.*)\\/(?<subsystem>[a-zA-z]+)\\/(?<name>[a-zA-z]+)";
      //size_t maxGroups = 4;
    
      regex_t regexCompiled;
      //regmatch_t groupArray[maxGroups];
    
      int rc;
      if ((rc = regcomp(&regexCompiled, regexString, REG_EXTENDED)) != 0)
        {
          char buffer[1024];
          regerror(rc, &regexCompiled, buffer, sizeof(buffer));
          printf("Could not compile regular expression (%d: %s).\n", rc, buffer);
          return 1;
        }
      regfree(&regexCompiled);
    
      return 0; 
    }
    

    我得到了输出:

    Could not compile regular expression (13: repetition-operator operand invalid).
    

    问题在于您使用的符号(?

    "(?<action>[a-zA-Z]+)@\\/(?<dev_path>.*)\\/(?<subsystem>[a-zA-z]+)\\/(?<name>[a-zA-z]+)"
    

    该符号适用于PCRE,而不是 POSIX。而 PCRE 在 ( 之后使用 ? 正是因为它在其他正则表达式系统(例如 POSIX)中无效。

    所以,如果您想使用 PCRE 正则表达式,请安装并使用 PCRE 库。

    否则,您需要使用:

    "([a-zA-Z]+)@\\/(.*)\\/([a-zA-z]+)\\/([a-zA-z]+)"
    

    有了这个,并注意到您需要一个 regmatch_t 来表示匹配的整个字符串以及 4 个捕获的组(总共 5 个捕获),您可以编写:

    #include <stdio.h>
    #include <string.h>
    #include <regex.h>
    
    int main(void)
    {
        char *source = "change@/devices/soc/799999.i2c/i2c-3/3-0015/power_supply/battery";
        // char * regexString = "(?<action>[a-zA-Z]+)@\\/(?<dev_path>.*)\\/(?<subsystem>[a-zA-z]+)\\/(?<name>[a-zA-z]+)";
        size_t maxGroups = 5;
        char *regexString =  "([a-zA-Z]+)@\\/(.*)\\/([a-zA-z]+)\\/([a-zA-z]+)";
    
        regex_t regexCompiled;
        regmatch_t groupArray[maxGroups];
    
        int rc;
        if ((rc = regcomp(&regexCompiled, regexString, REG_EXTENDED)) != 0)
        {
            char buffer[1024];
            regerror(rc, &regexCompiled, buffer, sizeof(buffer));
            printf("Could not compile regular expression (%d: %s).\n", rc, buffer);
            return 1;
        }
        if ((rc = regexec(&regexCompiled, source, maxGroups, groupArray, 0)) != 0)
        {
            char buffer[1024];
            regerror(rc, &regexCompiled, buffer, sizeof(buffer));
            printf("Could not execute regular expression (%d: %s).\n", rc, buffer);
            return 1;
        }
    
        printf("Match successful:\n");
        for (size_t i = 0; i < maxGroups; i++)
        {
            int so = groupArray[i].rm_so;
            int eo = groupArray[i].rm_eo;
            printf("%zu: %d..%d [%.*s]\n", i, so, eo, eo - so, &source[so]);
        }
    
        regfree(&regexCompiled);
    
        return 0;
    }
    

    输出是:

    Match successful:
    0: 0..64 [change@/devices/soc/799999.i2c/i2c-3/3-0015/power_supply/battery]
    1: 0..6 [change]
    2: 8..43 [devices/soc/799999.i2c/i2c-3/3-0015]
    3: 44..56 [power_supply]
    4: 57..64 [battery]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-31
      • 2012-07-01
      相关资源
      最近更新 更多