C の正規表現:例?

正規表現は実際には ANSI C の一部ではありません。ほとんどの (すべての?) *nix に付属する POSIX 正規表現ライブラリについて話しているように思えます。 C で POSIX 正規表現を使用する例を次に示します (これに基づく):

#include <regex.h>        
regex_t regex;
int reti;
char msgbuf[100];

/* Compile regular expression */
reti = regcomp(&regex, "^a[[:alnum:]]", 0);
if (reti) {
    fprintf(stderr, "Could not compile regex\n");
    exit(1);
}

/* Execute regular expression */
reti = regexec(&regex, "abc", 0, NULL, 0);
if (!reti) {
    puts("Match");
}
else if (reti == REG_NOMATCH) {
    puts("No match");
}
else {
    regerror(reti, &regex, msgbuf, sizeof(msgbuf));
    fprintf(stderr, "Regex match failed: %s\n", msgbuf);
    exit(1);
}

/* Free memory allocated to the pattern buffer by regcomp() */
regfree(&regex);

または、Perl と互換性のある C の正規表現のライブラリである PCRE を確認することもできます。Perl の構文は、Java、Python、および他の多くの言語で使用されているものとほとんど同じ構文です。 POSIX 構文は grep で使用される構文です 、 sedvi など


おそらくあなたが望むものではありませんが、re2c のようなツールは POSIX(-ish) 正規表現を ANSI C にコンパイルできます。これは lex の代わりとして書かれています。 、しかし、このアプローチでは、本当に必要な場合は、最後の速度のために柔軟性と読みやすさを犠牲にすることができます.


man regex.h regex.h の手動エントリはないと報告されていますが、man 3 regex パターン マッチング用の POSIX 関数を説明するページが表示されます。
同じ関数が The GNU C Library:Regular Expression Matching で説明されており、GNU C Library が POSIX.2 インターフェイスと GNU C Library が長年持っていたインターフェイスの両方をサポートしていることを説明しています。

たとえば、引数として渡された文字列のうち、最初の引数として渡されたパターンと一致する文字列を出力する仮想プログラムの場合、次のようなコードを使用できます。

#include <errno.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void print_regerror (int errcode, size_t length, regex_t *compiled);

int
main (int argc, char *argv[])
{
  regex_t regex;
  int result;

  if (argc < 3)
    {
      // The number of passed arguments is lower than the number of
      // expected arguments.
      fputs ("Missing command line arguments\n", stderr);
      return EXIT_FAILURE;
    }

  result = regcomp (&regex, argv[1], REG_EXTENDED);
  if (result)
    {
      // Any value different from 0 means it was not possible to 
      // compile the regular expression, either for memory problems
      // or problems with the regular expression syntax.
      if (result == REG_ESPACE)
        fprintf (stderr, "%s\n", strerror(ENOMEM));
      else
        fputs ("Syntax error in the regular expression passed as first argument\n", stderr);
      return EXIT_FAILURE;               
    }
  for (int i = 2; i < argc; i++)
    {
      result = regexec (&regex, argv[i], 0, NULL, 0);
      if (!result)
        {
          printf ("'%s' matches the regular expression\n", argv[i]);
        }
      else if (result == REG_NOMATCH)
        {
          printf ("'%s' doesn't the regular expression\n", argv[i]);
        }
      else
        {
          // The function returned an error; print the string 
          // describing it.
          // Get the size of the buffer required for the error message.
          size_t length = regerror (result, &regex, NULL, 0);
          print_regerror (result, length, &regex);       
          return EXIT_FAILURE;
        }
    }

  /* Free the memory allocated from regcomp(). */
  regfree (&regex);
  return EXIT_SUCCESS;
}

void
print_regerror (int errcode, size_t length, regex_t *compiled)
{
  char buffer[length];
  (void) regerror (errcode, compiled, buffer, length);
  fprintf(stderr, "Regex match failed: %s\n", buffer);
}

regcomp() の最後の引数 少なくとも REG_EXTENDED である必要があります 、または関数は基本的な正規表現を使用します。つまり、(たとえば) a\{3\} を使用する必要があります。 a{3} の代わりに

POSIX.2 には、ワイルドカード マッチング用の別の関数もあります:fnmatch() .正規表現をコンパイルしたり、部分式に一致する部分文字列を取得したりすることはできませんが、ファイル名がワイルドカードに一致するかどうかを確認するのは非常に特殊です (たとえば、FNM_PATHNAME を使用します)。 フラグ)