Posix正则表达式非贪心

有没有办法在C中使用非贪婪的正则表达式,就像可以在Perl中使用? 我尝试过几件事,但实际上并没有用。

我目前正在使用这个与IP地址和相应的HTTP请求匹配的正则表达式,但是虽然我使用的是*?但它很贪婪

([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1

在此示例中,它始终匹配整个字符串:

 #include  #include  int main() { int a, i; regex_t re; regmatch_t pm; char *mpages = "TEST 127.0.0.1 GET /test.php HTTP/1.1\" 404 525 \"-\" \"Mozilla/5.0 (Windows NT HTTP/1.1 TEST"; a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED); if(a!=0) printf(" -> Error: Invalid Regex"); a = regexec(&re, &mpages[0], 1, &pm, REG_EXTENDED); if(a==0) { for(i = pm.rm_so; i < pm.rm_eo; i++) printf("%c", mpages[i]); printf("\n"); } return 0; } 

$ ./regtest

127.0.0.1 GET /test.php HTTP / 1.1“404 525” – “”Mozilla / 5.0(Windows NT HTTP / 1.1

不,POSIX正则表达式中没有非贪心量词。 但是有一个库为C提供类似perl的正则表达式: http : //www.pcre.org/

正如我之前在评论中所说的那样,使用grep -E来运行POSIX正则表达式的测试,这样就可以改善开发时间。 无论哪种方式,似乎你的问题是正则表达式而不是缺少的function。

我不太清楚你想从请求中获取什么…假设你只想要IP地址,HTTP动词和资源,最终可能会得到以下正则表达式。

 regcomp(&re, "\\b(.?[0-9])+\\s+(GET|POST|PUT)\\s+([^ ]+)", REG_EXTENDED); 

请注意已经做出了一些假设。 例如,这个正则表达式假设IP地址将很好地形成,它还假设一个HTTP动词请求GET,POST,PUT。 根据您的需求进行编辑。

使正则表达式与下一个单词匹配的强制方法是:

 "([^H]|H[^T]|HT[^T]|HTT[^P]|HTTP{^/]|HTTP/[^1]|HTTP/1[^.]|HTTP/1\\.[^1])*HTTP/1\\.1" 

除非你能更聪明地了解你的比赛 – 你可以: HTTP请求

 Request-Line = Method SP Request-URI SP HTTP-Version CRLF 

并且右侧没有任何非终结符合嵌入空格。 所以:

 "[0-9]{1,3}(\\.[0-9]{1,3}){3} [^ ]* [^ ]* HTTP/1\\.1" 

因为你只是为整个表达式匹配分配空间,或者将parens重新放入以获得碎片。

 a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED|REG_ENHANCED); 

在过去没有这个宏

 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \ || __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 #define REG_ENHANCED 0400 /* Additional (non-POSIX) features */ #endif 

在您的代码中, pm应该是一个regmatch_t数组,在您的情况下,应该至少有2到4个元素,具体取决于您要捕获的()子表达式。

你只有一个元素。 第一个元素pm[0]总是获得与整个RE匹配的任何文本。 这就是你将获得的那个。 pm[1]将获得第一个()子表达式(IP地址)的文本,而pm[3]将获得与您的(.*?)术语匹配的文本。

但即便如此,如上所述(Wumbley,WQ),POSIX正则表达式库可能不支持非贪婪量词。