9

有没有一种方法可以在 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

4

5 回答 5

6

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

于 2013-11-27T11:46:48.927 回答
0

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

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

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

请注意,已经做出了几个假设。例如,此正则表达式假定 IP 地址格式正确,它还假定请求带有 HTTP 动词 GET、POST、PUT。根据您的需要进行编辑。

于 2013-11-27T12:32:36.133 回答
0

让正则表达式匹配下一个单词出现的蛮力方法是:

"([^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"

因为您只是为整个表达式匹配分配空间,或者将括号放回原处以获取碎片。

于 2013-11-27T13:03:57.540 回答
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
于 2017-03-06T10:30:15.553 回答
-1

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

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

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

于 2015-11-11T02:20:51.530 回答