2013-11-27 105 views
6

有没有一种方法可以在C中使用非贪婪的正则表达式,就像在Perl中可以使用的那样? 我尝试了几件事,但实际上并不奏效。posix正则表达式非贪婪

我目前使用此正则表达式匹配的IP地址和相应的HTTP请求,但尽管我使用的是*?:

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

在这个例子中,它总是相匹配的贪婪整个字符串:

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

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

+1

您可以将输入的字符串添加到该问题。 [它似乎为我工作。](http://regexr.com?37cvn) – OGHaza

+1

我不知道'c'所以不能建议,但问题是在你的代码[不是你的正则表达式](http: //regexr.com?37cvt)。如果您在输入字符串的末尾添加更多内容,可能会明显看出它不匹配第二个“HTTP/1.1”,而是返回整个输入字符串。 – OGHaza

+0

您可以使用更准确的IP匹配。检查这个答案:http://stackoverflow.com/a/106223/363573 – Stephan

回答

5

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

0

正如我在之前的评论中所说的,使用grep -E来运行POSIX正则表达式测试,这样开发时间将会得到改善。无论哪种方式,看起来你的问题是正则表达式,而不是缺少的功能。

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

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

请注意已经做出了一些假设。例如,这个正则表达式假定IP地址将会很好地形成,它也会假设一个带有GET,POST,PUT的HTTP动作的请求。按照您的需求编辑。

0

得到一个正则表达式匹配一个字的下一个出现的强制方法是:

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

,除非你能得到你的对手更聪明 - 你可以:HTTP requests

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

并且右侧的非终止符都不匹配嵌入的空格。因此:

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

因为您只为整个表达式匹配分配空间,或者将parens放回来获取块。

-1

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

您只有一个元素。第一个元素pm[0]总是获得与您的整个RE相匹配的任何文本。这就是你会得到的。它将获得第一个()子表达式(IP地址)和pm[3]的文本,它们将获得与您的(.*?)术语匹配的文本。尽管如此,如上所述(由Wumbley,W.Q.提供),POSIX正则表达式库可能不支持非贪婪量词。

0
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