3

CのPCREregexlib(http://www.pcre.org/)を使用して、HTML文字列を解析および照合しています。質問を単純化するために、ソース文字列"aaa:bbbb:"、およびパターン:a(。*?):| b(。*?) :、記号欲張りでない一致であることを示すので、答えは2つの一致である必要があります。1つは「aaa:」で、もう1つは「bbbb:」です

それから私はプログラムしました:

char *src = "aaa:  bbbb:";
char *pattern = "a(.*?):|b(.*?):";
pcre *re = NULL;

//---missing out---

re = pcre_compile(pattern,  // pattern,  
                  0,            // options,   
                  &error,       // errptr,   
                  &erroffset,   // erroffset,  
                  NULL);        // tableptr, 
while (
      (rc = pcre_exec(re,     // regex ptr,   
               NULL,          // extra arg,   
               src,           // subject,   
               strlen(src),   // length,   
               0,             // startoffset,   
               0,             // options,   
               ovector,       // ovector,   
               OVECCOUNT)     // ovecsize,   
      )!=PCRE_ERROR_NOMATCH)  
    {
       printf("\nOK, string has matched ...there are %d matchups\n\n",rc); //  
       for (i = 0; i < rc; i++)
       {
            char *substring_start = src + ovector[2*i];
            int substring_length = ovector[2*i+1] - ovector[2*i];
            printf("$%2d: %.*s length: %d\n", i, substring_length, substring_start,substring_length);
       }
       src = src + ovector[1];  // to move the src pointer to the end offset of current matchup
       if (!src) break;
    }
pcre_free(re);

結果が出ました:

Source : aaa:  bbbb:
Pattern: "a(.*?):|b(.*?):"

OK, string has matched ...there are 2 matches

$ 0: aaa: length: 4
$ 1: aa length: 2 

OK, string has matched ...there are 3 matches

$ 0: bbbb: length: 5
$ 1:  length: 0
$ 2: bbb length: 3

そして、どうやって「$ 1:長さ:0」という答えが得られたのだろうか。

// ------------------------------------------------ ----------------------------------------

@ジョナサンレフラーあなたの答えは正しいと思います。

今試してみました

Source: "aaa: bbb: ccc:"
Pattern: "c(.+?):|a(.+?):|b(.+?):"

結果は次のようになります。

$ 0: aaa: length: 4
$ 1:  length: 0
$ 2: aa length: 2

$ 0: bbbb: length: 5
$ 1:  length: 0
$ 2:  length: 0
$ 3: bbb length: 3

$ 0: cccc: length: 5
$ 1: ccc length: 3

これはあなたの答えを逆に証明します:

マッチアップが見つかると正規表現のキャプチャが停止するため、マッチを試行した後aaa:にキャプチャされ、結果の最初の行は文字列全体を示し、#2は代替と一致する結果オフセットを示しますa(.+?):c(.+?):c(.+?):

b(。+?)の場合、2つを説明する正規表現でようやくキャプチャされましたlength : 0

c(。+?)の場合、そもそもキャプチャされたので、length : 0

4

4 に答える 4

1

正規表現には2つのキャプチャがあり、各選択肢に1つずつあります。ただし、キャプチャには左から右に番号が付けられます。2番目のケースでは、最初の($1)キャプチャは空です。a一致するものに'がなかったため、最初のキャプチャは空です。2番目の($2)キャプチャには、b期待どおりの'が含まれています。

最初に一致したときに2回目のキャプチャに何も指定されていなかったことは、ほとんど驚くべきことです。データがなかった場合、キャプチャは空だと思います。

于 2013-03-06T14:19:07.623 に答える
0

A*は、ゼロを含む任意の数の文字を示します。つまり、「何もない」と一致します。+代わりに、「少なくとも1つ一致する」ことを示す文字を使用する必要があります。

于 2013-03-06T12:13:41.220 に答える
0

パターンを使ってみてくださいchar *pattern = "a+?:|b+?:";

編集ちょうど"a+:|b+:"また働くことに気づいた。

于 2013-03-06T12:28:50.453 に答える
0

パターン:

a(.*?):

このパターンは、キャプチャされていない'a'を探し、続いて任意の量の何かをキャプチャし、最小の一致パターンを返すように変更し、その後にキャプチャされていない':'を検索することを意味します。

文字列を検討する場合:

aaa:

次に、コロンの前の最後の「a」について考えます。

a:

これはパターンに一致します。「a」の後に何も続きません。その後にコロンが続きます。'nothing'がキャプチャされるため、長さがゼロの結果が得られます。

于 2013-03-06T14:27:28.650 に答える