正規表現で使う関数は次のように定義されている。
これらを使って正規表現をつかった検索を行う。
# include<regex.h>
int regcomp(regex_t *preg, const char *regex, int cflags);
int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);
void regfree(regex_t *preg);
step1
まず、regcompを使って正規表現文字列をregexecで使えるようにコンパイルを行う。
regexに正規表現文字列を指定し、コンパイルされたものはpregに格納される。
cflagはregexecに対して影響を与えるフラグである。意味は以下の表の通り。
cflag | 意味 |
---|---|
REG_EXTENDED | 拡張正規表現で検索を行う。 |
REG_ICASE | 大文字小文字を無視する。 |
REG_NOSUB | マッチした位置を教えない。 |
REG_NEWLINE | 全ての文字にマッチするオペレータに改行をマッチさせない。 |
step2
次に、regexecを使って検索を行う。
pregにはregcompでコンパイルしたものを検索範囲となる文字列を指定する。
nmatchとpmatch[]はマッチした位置を取得するために使用するもの。
eflagsはregexecに対して影響を与えるフラグである。意味は以下の表の通り。
eflag | 意味 |
---|---|
REG_NOTBOL | 行頭にマッチするオペレータが失敗する。 |
REG_NOTEOL | 行末にマッチするオペレータが失敗する。 |
regexecは失敗時にREG_NOMATCHを返す。
マッチする文字列が無い場合もREG_NOMATCHを返す。
step3
regcompはregex_t構造体の中にマロックした領域を保存するようになっているため、これを解放するためにregfreeで最後に解放する。
エラー処理
regcompは失敗時にはエラーコードを返すようになっている。
このエラーコードを文字列化するにはregerrorを使う。
例
grepコマンド的なものを作ってみる。
example.c
# include <stdio.h>
# include <stdlib.h>
# include <regex.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "usage:\n%s PATTERN FILENAME\n", argv[0]);
exit(1);
}
int err;
char err_str_buf[4096] = {0};
// STEP1
regex_t patbuf;
err = regcomp(&patbuf, argv[1], REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
if (err != 0) {
regerror(err, &patbuf, err_str_buf, sizeof(err_str_buf));
fprintf(stderr, "regcomp: %s\n", err_str_buf);
exit(1);
}
FILE *fp;
char buf[1024] = {0};
fp = fopen(argv[2], "r");
if (fp == NULL) {
perror(argv[1]);
exit(1);
}
//STEP2
while(fgets(buf, sizeof(buf), fp)) {
if (regexec(&patbuf, buf, 0, NULL, 0) == 0) {
fputs(buf, stdout);
}
}
//STEP3
regfree(&patbuf);
fclose(fp);
return 0;
}
実行結果
$ gcc -o example_program example.c
$ ./example_program reg.* example.c
# include <regex.h>
regex_t patbuf;
err = regcomp(&patbuf, argv[1], REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
regerror(err, &patbuf, err_str_buf, sizeof(err_str_buf));
fprintf(stderr, "regcomp: %s\n", err_str_buf);
if (regexec(&patbuf, buf, 0, NULL, 0) == 0) {
regfree(&patbuf);
参考