Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-regexec返回NOMATCH-即使它应该返回?_C_Regex_C99 - Fatal编程技术网

C-regexec返回NOMATCH-即使它应该返回?

C-regexec返回NOMATCH-即使它应该返回?,c,regex,c99,C,Regex,C99,正则表达式模式需要匹配以下内容: abc_xyz_0 abc_1025_01.29.00_xyz_0 abc_0302_42.01.00_xyz_0 (abc和xyz之间的数字无关紧要) 因此,我分析: (abc_(\w+\.\d+\.\w+)?xyz_0) 我的代码: regex_t r; unsigned int maxGroups = 3; regmatch_t groupArray[maxGroups]; char * to_match = "abc_0302_02.01.00_x

正则表达式模式需要匹配以下内容:

abc_xyz_0
abc_1025_01.29.00_xyz_0
abc_0302_42.01.00_xyz_0 
(abc和xyz之间的数字无关紧要)

因此,我分析:

(abc_(\w+\.\d+\.\w+)?xyz_0)
我的代码:

regex_t r;
unsigned int maxGroups = 3;
regmatch_t groupArray[maxGroups];
char * to_match = "abc_0302_02.01.00_xyz_18 abc_0302_02.01.00_xyz_16 abc_0302_02.01.00_xyz_14 abc_0302_02.01.00_xyz_0 abc_0302_02.01.00_xyz_10 abc_0302_02.01.00_xyz_2"

if (0 != regcomp(&r, "(abc_(\\w+\\.\\d+\\.\\w+)?xyz_0)", REG_EXTENDED)) 
{
    //this does NOT get hit
    printf("regcomp failed")
}
else if(regexec(r, to_match, maxGroups, groupArray, REG_EXTENDED) == 0)
 { *never gets here* }
else
 { printf("regexec returned non-zero(No Matches)\n"); }

regfree(&r);
所以我猜要么我的正则表达式错了(这对我上面定义的案例很好用——我用regexpal.com来确认),要么我遗漏了什么


无论哪种方式,我都知道我很接近,非常感谢您的帮助。

您复制到问题中的代码中有几个拼写错误(见下文),您只需将
REG_EXTENDED
传递到
regcomp
regexec
识别的唯一标志是
REG\u NOTBOL
REG\u NOTEOL
。(有关详细信息,请参阅。)

然而,问题是Posix正则表达式,包括Gnu实现,没有实现非标准转义序列
\d
。如中所示,模式可以包括:

一个“\”后跟一个字符“^.[$()|*+?{\”(匹配作为普通字符的该字符)

后跟任何其他字符的“\”(与作为普通字符的该字符匹配,就好像“\”不存在一样)

请注意,
\
的唯一效果是,在任何一种情况下,都会导致以下字符作为普通字符进行匹配。
regcomp
的Gnu实现确实将
\w
识别为字符类,但Posix不需要这种行为,其他实现可能不会这样做。(它也没有文档记录,因此可能并不总是有效。)并且它无法识别
\d

如果使用Posix正则表达式,则应使用Posix标准字符类,因此正则表达式字符串应为:

"(abc_([[:alnum:]_]+\\.[[:digit:]]+\\.[[:alnum:]_]+)?xyz_0)"
您将在上一个链接的regex手册页中找到一个Posix命名字符类列表(或者键入
man 7 regex
,假设您安装了标准库文档,强烈建议这样做)

在调用
regexec
r
更改为
&r
之后,我用您的代码验证了这一点

请注意,很少有在线正则表达式资源实现Posix正则表达式规范;例如,只提供PCRE和Javascript样式正则表达式的选项


每次调用
regexec
,都会根据以下所述的固定算法获得传递给它的字符串中的第一个匹配项:

如果RE可以匹配 给定的字符串,RE匹配字符串中最早开始的字符串。 如果RE可以匹配从该点开始的多个子字符串, 它匹配最长的。子表达式也匹配最长的 可能的子字符串,受整个匹配的约束 尽可能长,子表达式在 我们优先于以后开始的。请注意,更高级别的 因此,子表达式优先于其较低级别的组件 子表达式


如果要在同一字符串中查找一个模式的多个实例,则需要在循环中调用
regexec
。每次通过循环时,您都会给它上一次匹配的第一个不匹配字节的地址(即
string+matches[0]。rm_eo
)如果您在匹配中依赖
^
锚定,则需要将
REG\u NOTBOL
标志的正确值传递给对
regexec

的每次调用,它与此
abc(?:\ud+\ud+.\d+.\d+.\d+)?\u xyz\u 0
@sln我真的很感谢您的帮助,但这对我不起作用。添加了“:”,regcomp失败。这对我不起作用。(abc\uu(\?:\\w+\.\\d+\\.\\w+)\xyz\u 0)非常感谢您的帮助。接下来的问题:如果我想要一个非捕获组,我该怎么做?在执行“regexec()”之后,我只想要一个捕获组,而不是多个。原因是如果我有多个abc#############################################+xyz#u 0非捕获组?:未被识别,并且我在手册页中没有看到任何内容。使用建议的正则表达式字符串执行(缓冲区中只有一个匹配项),我得到两个“abc############xyz u 0”和“#35;。接收2+个组是可以的,但前提是缓冲区中有2+个匹配项。同时为语法错误道歉,regex/buffer比问题中复杂得多,所以我试图通过删除函数调用等来简化代码,以便普通读者能够理解。@GraysonHenry:每次调用
regexec时,它将只返回一个匹配项,并填充该匹配项的捕获。这是(大多数)正则表达式库的工作方式。您提供多个匹配组是因为您希望从同一匹配项中获取多个捕获项。Posix正则表达式不支持
(?:…)
不捕获组的语法,部分原因是捕获非常便宜。只需忽略您不关心的捕获。您不必为正则表达式中的所有捕获提供空间的匹配数组,只要告诉
regexec
您要捕获的组数。我正在解析的buff已生成,因此我是不确定我期望的匹配数。如果找到多个匹配,我将捕获每个匹配,然后向用户建议他们希望使用的匹配。我可以每隔一个匹配转发一次以避免重复,但这似乎是额外的逻辑。我只是想知道如果只有一个匹配,是否有其他方法仅捕获一个匹配在缓冲区中。对于我尝试执行的操作,我建议的正则表达式是否有任何错误,或者是否有更简单的方法:“abc_xyz_0 | abc_[[:alnum:][u]+\.[:digit:][]+\.[:alnum:][uz]+xyz?”