9

Perl で使用できるように、C で非貪欲な正規表現を使用する方法はありますか? いろいろ試してみましたが、実際にはうまくいきません。

私は現在、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

正規表現を単語の次の出現まで一致させる力ずくの方法は次のとおりです。

"([^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 に答える
-1

あなたのコードでpmは、 の配列である必要がregmatch_tあり、あなたの場合、キャプチャする () サブ式に応じて、少なくとも 2 ~ 4 個の要素が必要です。

要素は 1 つだけです。最初の要素 はpm[0]常に、RE 全体に一致するテキストを取得します。それはあなたが得るものです。pm[1]最初の () 部分式 (IP アドレス)のテキストをpm[3]取得し、用語に一致するテキストを取得します(.*?)

しかし、そうであっても、上で述べたように (Wumbley、WQ によって)、POSIX 正規表現ライブラリは非貪欲な量指定子をサポートしていない可能性があります。

于 2015-11-11T02:20:51.530 に答える