14

次のように、すべての一致位置を str で返したい場合:

abcd123abcd123abcd

すべての「abcd」を取得したい場合、regexec() を使用し、最初の位置を取得する必要があります:0、3、次に使用します:

123abcd123abcd

regexec() を再度使用するための新しい文字列として、など。regexec() に関するマニュアルを読んだところ、次のように書かれています。

int regexec(const regex_t *preg, const char *string, size_t nmatch,
               regmatch_t pmatch[], int eflags);
nmatch and pmatch are used to provide information regarding the location of any 
matches.

しかし、なぜこれがうまくいかないのですか?これは私のコードです:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>

int main(int argc, char **argv)
{
   int i = 0;
   int res;
   int len;
   char result[BUFSIZ];
   char err_buf[BUFSIZ];
   char* src = argv[1];  

   const char* pattern = "\\<[^,;]+\\>";
   regex_t preg;

   regmatch_t pmatch[10];

   if( (res = regcomp(&preg, pattern, REG_EXTENDED)) != 0)
   {
      regerror(res, &preg, err_buf, BUFSIZ);
      printf("regcomp: %s\n", err_buf);
      exit(res);
   }

   res = regexec(&preg, src, 10, pmatch, REG_NOTBOL);
   //~ res = regexec(&preg, src, 10, pmatch, 0);
   //~ res = regexec(&preg, src, 10, pmatch, REG_NOTEOL);
   if(res == REG_NOMATCH)
   {
      printf("NO match\n");
      exit(0);
   }
   for (i = 0; pmatch[i].rm_so != -1; i++)
   {
      len = pmatch[i].rm_eo - pmatch[i].rm_so;
      memcpy(result, src + pmatch[i].rm_so, len);
      result[len] = 0;
      printf("num %d: '%s'\n", i, result);
   }
   regfree(&preg);
   return 0;
}

./regex 'hello, world'

出力:

num 0: 'hello'

これは私の尊敬の出力です:

num 0: 'hello'
num 1: 'world'
4

1 に答える 1

18

regexec正規表現一致を実行します。一致が見つかると、regexec は 0 を返します (一致の成功)。パラメータpmatchには、その 1 つの一致に関する情報が含まれます。最初の配列インデックス (つまりゼロ) には一致全体が含まれ、後続の配列インデックスにはキャプチャ グループ/サブ式に関する情報が含まれます。

デモンストレーションするには:

const char* pattern = "(\\w+) (\\w+)";

「hello world」で一致すると、次のように出力されます。

num 0: 'hello world'  - entire match
num 1: 'hello'        - capture group 1
num 2: 'world'        - capture group 2

(実際に見てください

ほとんどの正規表現環境では、求める動作は、グローバル修飾子 /g を使用して取得できた可能性があります。Regexec は、この修飾子をフラグとして提供したり、修飾子をサポートしたりしません。したがって、すべての一致を取得するには、前の一致の最後の文字から始まる regexec がゼロを返す間、ループする必要があります

グローバル修飾子は、PCRE ライブラリ (有名な正規表現 C ライブラリ) を使用しても使用できません。PCREのマニュアルページには、これについて次のように書かれています。

適切な引数を指定して pcre_exec() を複数回呼び出すことにより、Perl の /g オプションを模倣できます。

于 2013-05-09T20:00:55.723 に答える