【问题标题】:What does an empty regular expression mean in POSIX BRE/ERE?POSIX BRE/ERE 中的空正则表达式是什么意思?
【发布时间】:2016-03-15 07:41:31
【问题描述】:

以下面的 API regex_match 为例,如果我用 regex_match(any_string_here,"") 调用它,你可以看到我在这里传递了一个空的正则表达式,那么它总是返回 0,表示匹配成功。那么,POSIX BRE/ERE 中的空正则表达式是什么意思?

空正则表达式意味着我将 "" 传递给 glibc regcomp 函数。请参阅以下示例。

int regex_match( const char* haystack, const char* needle )
{
        regex_t needle_pattern;
        int regex_flag = REG_NOSUB | REG_EXTENDED;
        int rc = regcomp(&needle_pattern,needle, regex_flag);
        if (rc != 0){
                char error_msg[256];
                size_t error_len = 0;
                error_len = regerror(rc,&needle_pattern,error_msg,sizeof(error_msg));
                error_len = error_len < sizeof(error_msg) ? error_len : sizeof(error_msg) - 1;
                error_msg[error_len] = '\0';
                cout<<"compile error: "<<error_msg<<endl;
                regfree(&needle_pattern);
                return regcomp_error_base + rc;
        }
        rc = regexec(&needle_pattern, haystack, 0, NULL, 0);
        if ( (rc != 0) && (rc != REG_NOMATCH)){
                char error_msg[256];
                size_t error_len = 0;
                error_len = regerror(rc,&needle_pattern,error_msg,sizeof(error_msg));
                error_len = error_len < sizeof(error_msg) ? error_len : sizeof(error_msg) - 1;
                error_msg[error_len] = '\0';
                cout<<"exec error: "<<error_msg<<endl;
        }
        regfree(&needle_pattern);
        //regexec returns 0 if the regular expression matches
        return rc;
}

【问题讨论】:

  • 不确定empty 表达式的含义。我的意思是,是这个// 还是这个/^$//.*?/。我猜如果它什么都不匹配,它就不能被假定为一个空表达式,并且可能也没有说任何关于主题字符串的内容。最好的办法是在使用主题和正则表达式字符串之前测试它们的长度。
  • POSIX 正则表达式语法不允许空模式。行为未定义。您可能会遇到一个无限循环(MacOS C++ 就是这种情况)。
  • 我猜他们的关键字是它匹配的东西,虽然它从字面上什么都不匹配。
  • @sln 空正则表达式意味着我将 "" 传递给 glibc regcomp 函数。例如regcomp(&needle_pattern,"", regex_flag);
  • @stribizhev glibc 函数 regcomp 允许空的正则表达式,请看我的例子。

标签: regex posix glibc posix-ere


【解决方案1】:

这是我能找到的唯一参考资料 (source):

case regex_constants::__re_err_empty:
    return "An empty regex is not allowed in the POSIX grammar.";

这意味着由语言正则表达式实现来定义行为是什么,POSIX 与它几乎没有关系。

注意 regex.h 中缺少此错误!在您的情况下,您有一个空/空字符串匹配,因为您将空字符串作为模式传递。这是我在regex.c source code 中找到的:

对于某些模式,例如,(a?)?, p+j 这里指向
模式的结束。我们不想强调这样的观点,
因为当我们在上面恢复它时,进入开关会
p 递增到模式的末尾。我们不需要
推动这一点,因为我们显然不会再找到了
pend 之外的快速映射条目。 这样的模式可以匹配
不过是空字符串。

因此,如果执行单个搜索,则空模式匹配输入字符串中第一个符号之前的空字符串,如果执行全局搜索,则匹配所有符号之前的所有空字符串

【讨论】:

    【解决方案2】:

    一个空的正则表达式匹配一个空字符串。如果搜索字符串是空字符串,则匹配整个内容。而如果搜索字符串不为空,则匹配搜索字符串每个字符之间的空字符串。

    【讨论】:

      【解决方案3】:

      我猜“”会占用内存中的1个字节,即“\0”,而“any_string_here”在内存中看起来像“any_string_here\0”,所以“\0”总是匹配“any_string_here\0”。

      【讨论】:

        【解决方案4】:

        POSIX 与它无关。

        好吧,POSIX 定义了 BRE/ERE 的语法。例如:

        /* --------------------------------------------
           Extended Regular Expression
           --------------------------------------------
        */
        extended_reg_exp   :                      ERE_branch
                           | extended_reg_exp '|' ERE_branch
                           ;
        ERE_branch         :            ERE_expression
                           | ERE_branch ERE_expression
                           ;
        ERE_expression     : one_char_or_coll_elem_ERE
                           | '^'
                           | '$'
                           | '(' extended_reg_exp ')'
                           | ERE_expression ERE_dupl_symbol
                           ;
        one_char_or_coll_elem_ERE  : ORD_CHAR
                           | QUOTED_CHAR
                           | '.'
                           | bracket_expression
                           ;
        ERE_dupl_symbol    : '*'
                           | '+'
                           | '?'
                           | '{' DUP_COUNT               '}'
                           | '{' DUP_COUNT ','           '}'
                           | '{' DUP_COUNT ',' DUP_COUNT '}'
                           ;
        

        这个文法没有空正则表达式的产生式,即。 e.这是不允许的。

        【讨论】:

          猜你喜欢
          • 2022-12-05
          • 2017-11-23
          • 2011-06-15
          • 2012-06-10
          • 1970-01-01
          • 1970-01-01
          • 2012-09-07
          • 2011-08-28
          • 1970-01-01
          相关资源
          最近更新 更多