Posix正则表达式非贪心

时间:2013-11-27 10:26:01

标签: c regex posix non-greedy

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

我目前正在使用这个匹配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

5 个答案:

答案 0 :(得分:6)

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

提供类似perl的正则表达式

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分: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放回去获取碎片。

答案 3 :(得分: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

答案 4 :(得分:-1)

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

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

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