ここでCプログラム中でRegexのデータ構造と関数を使うための説明をする。 Regexは三つのインターフェース、GNUのためにデザインされたもの、 POSIXとの互換のためのもの、そしてBerkeley UNIXとの互換のための もの、を持っている。
もしあなたが、POSIXやBerkeley UNIXとの互換性を必要としない プログラムを書くのであれば、以下に挙げる関数を使うことができる。 それらの関数は他のインターフェースのものよりも多くのオプションを 設定できる。
与えられた正規表現をコンパイルし、マッチングし、検索するために パターンバッファを与えなければならない。パターンバッファは コンパイルされた正規表現を一つ保持する。(4)
複数の異なるパターンバッファを同時に持ち、 それぞれのパターンバッファで別の正規表現のコンパイルパターンを 保持することもできる。
`regex.h'でパターンバッファの構造体を以下のように定義している。
/* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ /* コンパイルしたパターンを保持するスペース。配列の添え字として 要素(の型)を使うことがあるので`unsigned char *'として 宣言している。 */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ /* `buffer'がポイントしてる領域のバイト数 */ unsigned long allocated; /* Number of bytes actually used in `buffer'. */ /* `buffer'で実際に使用しているバイト数 */ unsigned long used; /* Syntax setting with which the pattern was compiled. */ /* パターンがコンパイルされたときのシンタクスの設定 */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ /* fastmapへのポインタ、もしくはゼロ。fastmapが存在すれば re_searchは、それをマッチの先頭になりうるポジションまで スキップするのに使用する。*/ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ /* 比較を行う前にすべてのキャラクタに対して適用する 変換テーブル。もしくは変換を行わない場合にはゼロ。 変換はパターンをコンパイルするときと文字列のマッチングを 行うときにそれぞれ適用される */ char *translate; /* Number of subexpressions found by the compiler. */ /* コンパイラが認識した部分正規表現の数 */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ /* パターンが空文字列にマッチできないのであればゼロ、そうでなければ1。 */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ /* REGS_UNALLOCATEDであれば`regs'構造体の領域を `最大限(RENREGS, re_nsub + 1)'に割り当てる。 REGS_REALLOCATEのとき、必要に応じて再割当を行う。 REGS_FIXEDのとき、すでにあるものを使う */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ /* `regex_compile'がパターンをコンパイルするときにゼロにセットする。 fastmapをアップデートしたとき`re_compile_fastmap'が1にセットする。*/ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ /* セットされている場合、`re_match_2'は部分正規表現に関する 情報を返さない。*/ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ /* セットされている場合、beginning-of-line anchorは 文字列の先頭にマッチしない。*/ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ /* end-of-line anchorについて前者に同じ */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ /* 真である場合、改行にあるanchorはマッチする*/ unsigned newline_anchor : 1;
GNUでは、与えられた正規表現のマッチングと検索の両方を行うことが できる。そのどちらを行うにしても、まず最初に正規表現をコンパイルし、 パターンバッファ(セクション GNU Pattern Buffersを参照)にその結果をセットしなければ ならない。
正規表現のマッチングはそれがコンパイルされたときのシンタクスに従って
行われる。GNUでは、re_syntax_options
という変数
(`regex.h'で宣言され、`regex.c'で定義されている)に
望みの設定をコンパイル関数のre_compile_pattern
を呼び出す前にセットすれば良い。
セクション Syntax Bitsを参照, and セクション Predefined Syntaxesを参照.
re_syntax_options
の値は任意の時点で変更することができるが、
普通は一度セットしたら変更はしない。
re_compile_pattern
は引数にパターンバッファをとる。
あなたは以下のフィールドを初期化しなければならない。
translate initialization
translate
fastmap
buffer
allocated
re_compile_pattern
にコンパイルしたパターンのための
メモリの割り付けをさせたい場合、これら両方ともに0をセットする。
すでに持っているメモリブロック(malloc
で割り付けたもの)を
Regexに使わせたいのならば、buffer
にそのアドレスを、
allocated
にその大きさ(バイトで)をセットする。
re_compile_pattern
は必要に応じてコンパイルしたパターンのための
スペースを拡張するのに、realloc
を使用する。
パターンバッファをコンパイルするには次の関数を使う
char * re_compile_pattern (const char *regex, const int regex_size, struct re_pattern_buffer *pattern_buffer)
regexは正規表現のあるアドレス、regex_sizeはその長さ、 そしてpattern_bufferはパターンバッファのアドレスである。
re_compile_pattern
は正規表現のコンパイルに成功するとゼロを返し、
*pattern_buffer
にコンパイルしたパターンをセットする。
また、パターンバッファのフィールドは以下のようにセットされる。
buffer
used
syntax
re_syntax_options
の現在の値。
re_nsub
fastmap_accurate
buffer
に置かれている
パターンと異なっているという前提でゼロにする。
このような(コンパイルパターン無しにfastmapを作れない)場合、
fastmap
はincompatibleなfastmapであるか、意味の無いものである
re_compile_pattern
はregexをコンパイルできなかったときに
セクション POSIX Regular Expression Compilingを参照のエラーリストの一つを表す
エラー文字列を返す。
一度パターンをコンパイルしてパターンバッファ (セクション GNU Regular Expression Compilingを参照)に格納したならば、 マッチングルーチンに対して別の文字列がそのパターンに マッチするかどうかのチェックを次の関数を使って行うことができる。
int re_match (struct re_pattern_buffer *pattern_buffer, const char *string, const int size, const int start, struct re_registers *regs)
pattern_bufferはコンパイル後の内容が入るパターンバッファのアドレス である。stringはマッチングさせたい文字列 (改行やnullキャラクタを含んでいても良い)、 sizeはstringの長さ、startはマッチングを始めたい 文字列の場所のインデクス(stringの最初のキャラクタの インデクスはゼロ)である。 regsの詳しい解説はセクション Using Registersを参照。ここにゼロを渡すことも できる。
re_match
はpattern_bufferにある正規表現と
stringにある文字列のマッチングを
pattern_buffersのsyntax
フィールドに従って
行う(どのようにセットするかはセクション GNU Regular Expression Compilingを参照)。
この関数はコンパイルしたパターンがstringの一部にマッチしなかった
ときに@math{-1}を、内部的なエラーが発生したときに@math{-2}を返す。
そうでない場合、stringのどれくらいのキャラクタ(ゼロの場合もある)が
マッチしたのかを返す。
例: pattern_bufferが`a*'をコンパイルしたパターンが
入っているパターンバッファを指していて、stringが
`aaaaab'を指している(そしてsizeは6となる)とする。
startが2であればre_match
は3を返す。つまり
`a*'はstringの中の後ろ三つの`a'にマッチしたと
いうことである。startが0の場合には、re_match
は5を返す。
すなわち、stringの中の`a'全てにマッチしたということである。
startが5もしくは6であれば、ゼロが返る。
startが0からsizeの間にない場合、
re_match
は @math{-1}を返す。
Searchingとは文字列中の連続する位置でマッチングを試みるということである。
re_search
という関数がこれを行う。
re_search
を呼び出す前に、正規表現をコンパイルしておかなければならない。
セクション GNU Regular Expression Compilingを参照.
関数定義は以下の通り。
int re_search (struct re_pattern_buffer *pattern_buffer, const char *string, const int size, const int start, const int range, struct re_registers *regs)
re_match
(セクション GNU Matchingを参照)の引数とほぼ同じであるが、
違うのはre_match
の startという引数が
startとrangeという二つの引数に置き換えられていると
いうことである。
rangeが正の数であれば、re_search
は最初に
startの位置からマッチングを試み、失敗した場合には
@math{start + 1}の位置から試みる。という具合に
@math{start + range}まで続けて試みていく。
rangeが負の数であれば最初にstartの位置から、
それが失敗すれば@math{start -1}の位置から・・・と行う。
startがゼロからsizeの間にない場合、re_search
は
@math{-1}を返す。rangeが正の数であれば、re_search
は
必要に応じて@math{start + range - 1}が
ゼロからsizeの間にあるようにrangeを調整する。
同様にして、rangeが負の数であればre_search
は
@math{start + range + 1}がゼロからsizeの
間にあるようにrangeを調整する。
pattern_bufferのフィールドfastmap
がゼロであれば、
re_search
は連続位置のスタートをマッチングし、ゼロ以外なら
fastmap
を使ってより効果的に検索を行う。
セクション Searching with Fastmapsを参照.
re_search
はマッチするものが見つからなければ@math{-1}を、
マッチするもののが見つかればマッチしたものの先頭のインデクスを返す。
内部エラーが発生した場合には @math{-2}を返す。
re_match_2
とre_search_2
という関数を使うことによって
二つの文字列に分割されたデータのマッチングや検索を行うことができる。
The function:
int re_match_2 (struct re_pattern_buffer *buffer, const char *string1, const int size1, const char *string2, const int size2, const int start, struct re_registers *regs, const int stop)
この関数はre_match
(セクション GNU Matchingを参照)に似ているが、
違うのは二つのデータ文字列とそのサイズを渡すということと、
これ以上マッチングを試みたくないという境界を示すstopという
インデクスを渡すという点である。
re_match
と同様に、成功すればre_match_2
は
stringのマッチしたキャラクタの数を返す。
startとstopがセットされ、regsの内容が使われているときには
string1とstring2を連結されたものとみなす。
re_match_2
は@math{size1 + size2}を越える値を
返すことは決してない。
The function:
int re_search_2 (struct re_pattern_buffer *buffer, const char *string1, const int size1, const char *string2, const int size2, const int start, const int range, struct re_registers *regs, const int stop)
この関数はre_search
に対して先の関数と同様である。
もし、長い文字列から検索を行うのならば、fastmapを使うといい。 これが無い場合、検索ルーチンは文字列の連続したポジションでマッチを試みる。 一般的に文字列中の大部分のキャラクタは(検索対照の)先頭にマッチしない。 マッチ結果の先頭に来ることのできるキャラクタかどうかを 与えられたポジションでマッチを試みると、 テーブルを使ってチェックするよりも長い時間がかかる。 fastmapとはそのためのテーブルである。
より詳細にいうと、fastmapはあなたが使っているキャラクタセットの
キャラクタで添え字付けされる配列である。ASCIIエンコーディングでは
したがって、256の要素があるということになる。
与えたパターンバッファに対して、fastmapを使って検索を行いたいのであれば
配列を割り付け、そしてパターンバッファのfastmap
フィールドに
配列のアドレスをセットしなければならない。fastmapを自分でコンパイルしても
よいし、re_search
にやらせてもよい。fastmap
がゼロ以外であるとき、
最初にある特定のコンパイルパターンを使って検索を行うときに自動的に
コンパイルする。
fastmapを自分でコンパイルするには次の関数を使う。
int re_compile_fastmap (struct re_pattern_buffer *pattern_buffer)
pattern_bufferはパターンバッファのアドレスである。
cがパターンマッチの先頭に来ることができるのであれば、
re_compile_fastmap
はpattern_buffer->fastmap[c]
を
ゼロ以外にする。この関数はfastmapがコンパイルできれば@math{0}を、
内部的なエラーが発生した場合には@math{-2}を返す。
例えば、`|'が選択演算子でpattern_bufferが
`a|b'をコンパイルしたパターンを保持している場合、
re_compile_fastmap
はfastmap['a']
とfastmap['b']
をセットする(その他のものはしない)。
re_search
はfastmapを文字列を走査するのに使う。
文字列に含まれるキャラクタがfastmap中に見つかるまでチェックする。
その後でマッチングが行われる。マッチングが失敗すれば、
このプロセスを繰り返す。つまり、fastmapを使うことによって
re_search
は(マッチングの)スタート位置に来ることのない
キャラクタにたいしてマッチを試みるような時間を浪費しないですむのである。
re_search
がfastmapを使わないようにしたいのであれば、
re_search
を呼び出す前に
パターンバッファのfastmap
フィールドにゼロをセットすればよい。
一度パターンバッファのfastmap
フィールドを初期化すれば、
それを繰り返す必要は(たとえ新しいパターンをコンパイルするときでも)
ない。fastmapを使いたいのかどうかはフィールドに反映させる。
re_search
はfastmap
がnullなら何もしないし、
そうでない場合には新しいパターンのために新たにfastmapをコンパイルする。
パターンバッファのtranslate
フィールドに変換テーブルをセットすること
により、GNURegex関数群はその変換テーブルを使用して
全ての正規表現及び文字列のキャラクタを変換する。
変換テーブル(translate table)は、そこで使用しているキャラクタで
添え字付けされる、キャラクタの配列である。ASCIIのエンコーディング
では、変換テーブルは256個の要素を持つことになる。
Regexの関数はキャラクタcを見つけたとき、それをその場で
translate[c]
を使って変換する。ただし、そのキャラクタが
`\'の直後にある場合にはこの操作は行われない。
(このことにより、`\B'や`\b'といった演算子を常に
区別することができる)
例えば、すべての英小文字を対応する英大文字にマッピングしたテーブルは
大小文字の違いを無視したマッチングに使用できる。
(5)
そのようなテーブルは小文字を除いて自分自身がマッピングされたものであり、
小文字の部分はそれに対応する大文字がマッピングされたものになるだろう。
ASCIIのエンコーディングでは、次のようにしてテーブルを初期化する
(これをcase_fold
と呼ぼう)
for (i = 0; i < 256; i++) case_fold[i] = i; for (i = 'a'; i <= 'z'; i++) case_fold[i] = i - ('a' - 'A');
Regexに与えたパターンバッファに対して変換テーブルを使うようにさせるには
バッファのtranslate
フィールドにテーブルのアドレスをセットすればよい。
Regexに変換操作を行って欲しくないのであれば、このフィールドに
ゼロをセットすればよい。
テーブルの内容をパターンバッファやfastmapのコンパイルのとき、あるいは
マッチングや検索の最中に変更したら、奇妙な結果を得ることになるだろう。
正規表現中のグループは、正規表現が文字列全体にマッチするのと同じように 文字列の一部分(空でも良い)にマッチすることができる。 マッチングルーチンはグループ毎にマッチした部分文字列の 先頭と終端を記憶している。
マッチしたものを見つけだすためには、GNUのマッチング関数もしくは 検索関数((セクション GNU Matchingを参照 and セクション GNU Searchingを参照)の 引数regsにゼロ以外のものを渡せばよい。 すなわち、`regex.h'で定義されているような、この型の構造体のアドレス である。
struct re_registers { unsigned num_regs; regoff_t *start; regoff_t *end; };
(多分)num_regs番目の要素(後述)を除いて、
start
とend
の配列のi番目の要素は
パターン中にあるi番目のグループの情報を記録している
(この配列はCのポインタとして宣言されているが、それは
ただ単に長さ0の配列がすべてのCコンパイラで使えるわけではない
という理由からであり、単純に配列であると考えてよい)。
start
とend
の配列はマッチングルーチンに渡された
バッファのregs_allocated
フィールドの値によって、様々な方法で割り付けが行われる。
最も単純で、またおそらくは最も便利であるのはマッチングルーチンに
正規表現中にある全てのグループに関して情報を記録するのに
十分な領域を(再)割り付けさせるということである。
regs_allocated
がREGS_UNALLOCATED
であるならば、
マッチングルーチンは@math{1 + re_nsub}だけ割り付けを行う
(もう一つのフィールドはパターンバッファである。
セクション GNU Pattern Buffersを参照)。余分な要素には@math{-1}がセットされ、
regs_allocated
にREGS_REALLOCATE
がセットされる。
その結果、引数に同一のパターンバッファとregsを与えて呼び出すと、
マッチングルーチンは必要に応じてより大きな領域の再割り付けを行う。
これはパターンバッファの一部の代わりに、re_registers
構造体の
regs_allocated
フィールドを作成するのにより論理的なもの
といえるだろう。しかしこの場合には、呼び出し側が(呼び出しを行う前に)
構造体の初期化をする必要がある。
現在ある多くのプログラムはこの初期化を行っていないのだが、
とにかくそれを避けるのが良いだろう。
GNUの正規表現関数を使うのならば、
re_compile_pattern
はregs_allocated
に
REGS_UNALLOCATED
がセットされ、この動作が
デフォルトとなる。
xx document re_set_registers
POSIXではこれに反し異なったインターフェースを要求していて、
呼び出し側はマッチングルーチンが満たす固定長の配列を渡してやら
なければならない。したがって、regs_allocated
がREGS_FIXED
であれば、マッチングルーチンは単に配列を満たすだけである。
以下に挙げる例では構造体re_registers
中の情報レコード
について述べている(以下の例では全て、`('がopen-group演算子、
`)' がclose-group演算子である。また、文字 stringの
先頭のキャラクタは添え字0である)。
regs->start[i]
にi-th番目のグループを
構成する部分文字列の先頭の文字列中における添字を、
regs->end[i]
にその部分文字列の終端の添字をセット
する。関数はまた、regs->start[0]
と
regs->end[0]
に、パターン全体についての同様の情報をセット
する。
関数はregs->start[0]
とregs->end[0]
に
パターン全体に関しての同様の情報をセットする。
例えば、`((a)(b))'に対して`ab'のマッチングをすると
その結果は以下のようになる。
regs->start[0]
は0、regs->end[0]
は2
regs->start[1]
は0、regs->end[1]
は2
regs->start[2]
は0、regs->end[2]
は1
regs->start[3]
は1、regs->end[3]
は2
regs->start[0]
は0、in regs->end[0]
は2
regs->start[1]
は1、in regs->end[1]
は2
regs->start[i]
と
regs->end[i]
に@math{-1}をセットする。
`(a)*b'というパターンと`b'という文字列をマッチングしたとすると
その結果は、
regs->start[0]
は0、in regs->end[0]
は1
regs->start[1]
は@math{-1}、regs->end[1]
も@math{-1}
regs->start[i]
と
regs->end[i]
に長さ0の文字列の添え字を
セットする。
`(a*)b'というパターンと`b'という文字列をマッチングした場合、
次のような結果となる。
regs->start[0]
は0、regs->end[0]
は1
regs->start[1]
とregs->end[1]
は0
regs->start[j]
と
regs->end[j]
には
(もしマッチするものがあったのなら)j番目の
グループの最後にマッチしたものに関する情報が格納される。
例えば`((a*)b)*'というパターンと`abb'という文字列の
マッチングを行ったとき、group 2は最後に空文字列にまっちする。
したがってこの結果は以下のようになる。
regs->start[0]
は0、in regs->end[0]
は3
regs->start[1]
は2、regs->end[1]
は3
regs->start[2]
とregs->end[2]
はともに2
regs->start[0]
は0、regs->end[0]
は3
regs->start[1]
は2、regs->end[1]
は3
regs->start[2]
は0、regs->end[2]
は1
regs->start[i]
and
regs->end[i]
to @math{-1}, then it also sets
regs->start[j]
and
regs->end[j]
to @math{-1}.
`((a)*b)*c'というパターンと`c'という文字列の
マッチングを行ったときの結果は、
regs->start[0]
は0、regs->end[0]
は1
regs->start[1]
は@math{-1}、regs->end[1]
は@math{-1}
regs->start[2]
は@math{-1}、regs->end[2]
は@math{-1}
regex_t
(POSIXのパターンバッファのための型)は
re_pattern_buffer
の型と等価であるので
パターンバッファに割り当てた領域を開放するために
セクション Freeing POSIX Pattern Buffersを参照に記述されているPOSIX関数を
使うことができる。
パターンバッファを解放した後では、マッチング関数や検索関数を呼び出す前に
正規表現をもう一度コンパイル(セクション GNU Regular Expression Compilingを参照)
する必要がある。
もし、POSIX互換のコードを記述しなければならないのであれば 次に挙げる関数を使う必要があるだろう。これらの関数のインターフェースは POSIXのドラフト1003.2/D11.2により指定されている。
POSIX方式で与えられた正規表現をコンパイルしたり、マッチングするためには
GNUのときのようにパターンバッファを与えてやらなければならない
(セクション GNU Pattern Buffersを参照)。
POSIXのパターンバッファはregex_t
という型を持ち、
それはGNUのパターンバッファの型re_pattern_buffer
と
等価なものである。
POSIXでは、与えられた正規表現の検索のみを行え、マッチングを
することはできない。関数を使用するためには最初に
regcomp
を使ってパターンバッファをコンパイルしなければならない。
パターンバッファをコンパイルするには次の関数を使う。
int regcomp (regex_t *preg, const char *regex, int cflags)
pregは初期化されたパターンバッファのアドレス。 regexは 正規表現のアドレス。そして、cflagsはコンパイル時のフラグで、 Regexが参照するビットの集合である。 ここで使うことのできるビットは`regex.h'で次のように定義されている。
REG_EXTENDED
regcomp
はpregのsyntax
フィールドをそれに従って
セットする。
REG_ICASE
regcomp
はpregの
translate
フィールドに大小文字を無視するための変換テーブルを
セットし、それ以前にセットしたものを置き換える。
REG_NOSUB
no_sub
フィールドをセットするよう指示する。
詳しくはセクション POSIX Matchingを参照。
REG_NEWLINE
.
)を参照)
が改行にマッチしないようにする。
[
... ]
and [^
... ]
)を参照)
が改行にマッチするようにする。
^
)を参照)が、REG_NOTBOL
がセットされていても
改行の直後にある空文字列にマッチするようにする
(REG_NOTBOL
の説明はセクション POSIX Matchingを参照)。
^
)を参照)が、REG_NOTEOL
がセットされていても
改行の直前にある空文字列にマッチするようにする
(REG_NOTEOL
の説明はセクション POSIX Matchingを参照)。
regcomp
は正規表現のコンパイルに成功すると0を返し、
*pattern_buffer
にコンパイルしたパターンをセットする。
syntax
(which it sets as explained above)を除いて、
GNUのコンパイル関数(セクション GNU Regular Expression Compilingを参照)
と同じ様に、同じフィールドにセットする。
regcomp
は正規表現のコンパイルに失敗すると以下に挙げるリストの
エラーコードを返す
(明記していない限り、すべての例でbasic regular expression syntax
を使っている)。
REG_BADRPT
REG_BADBR
REG_EBRACE
REG_EBRACK
REG_ERANGE
REG_ECTYPE
REG_EPAREN
REG_ESUBREG
REG_EEND
REG_EESCAPE
REG_BADPAT
REG_ESIZE
REG_ESPACE
POSIX方式のマッチングとは、nullで終端された文字列をその先頭のキャラクタ から始めてマッチするかどうか試みるということである。 一度パターンをコンパイルして、パターンバッファに結果が格納されている (セクション POSIX Regular Expression Compilingを参照)のならば、 マッチングルーチンにたいして、そのパターンと文字列がマッチするか を問い合わせることができる。
int regexec (const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
pregはコンパイルしたパターンのためのパターンバッファのアドレス。 stringはマッチを試みる文字列。
pmatchについての説明はセクション Using Byte Offsetsを参照を参照のこと。
nmatchに0をセットして呼ぶか、コンパイル時にコンパイルフラグ
REG_NOSUB
をセットしてpregをコンパイルしたかすると、
regexec
はpmatchを無視する。
さもなければ、最低限nmatchという要素の割り付けをせねばならない。
regexec
はpmatch中のバイトオフセットを
nmatchに記録する。そして、
@math{pmatch[nmatch]
- 1}までの
使用していない要素に@math{-1}をセットする。
eflagsは実行時フラグ(具体的には
REG_NOTBOL
とREG_NOTEOL
の2ビットで、これらは`regex.h'
に定義されている)を特定する。
REG_NOTBOL
をセットするとmatch-beginning-of-line演算子
(セクション The Match-beginning-of-line Operator (^
)を参照)は常にマッチに失敗する。
これによって、必要なときには個々の行毎にマッチング
つまり、行毎に与えられたパターンをくり返し検索するということ
を行うことができる。
それはmatch-beginning-of-line演算子があってもなくても正しく
パターンに対して働くだろう。REG_NOTEOL
は同様に
match-end-of-line演算子(セクション The Match-end-of-line Operator ($
)を参照)
に対して作用する。
regexec
は、pregのsyntax
フィールド
(セクション POSIX Regular Expression Compilingを参照)
で指定される
シンタクスに従って、stringからpregにマッチするものを
見つけだそうとする。
この関数はコンパイルしたパターンがstringとマッチし、
REG_NOMATCH
(`regex.h'に定義されている)
が定義されていなかったときにゼロを返す。
regcomp
かregexec
のいずれかで失敗した場合、
(その関数は)0以外のエラーコードを返す。返却されるコードは
`regex.h'で定義されている。
それらのコードの意味は
セクション POSIX Regular Expression Compilingを参照とセクション POSIX Matchingを参照
を参照のこと。コードに対応するエラー文字列を取得するには
次の関数を使う。
size_t regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
errcodeはエラーコード、pregはエラーが起きたパターンバッファの アドレス、errbufはエラーバッファ、そしてerrbuf_sizeは errbufのサイズである。
regerror
はerrcodeに対応するエラー文字列のバイト長
(終端のnullキャラクタを含む)を返す。もし、errbufとerrbuf_sizeが
0以外であるならば、同様にerrbufにエラー文字列の
@math{errbuf_size - 1}文字がnullを終端につけて返される。
errbuf_sizeは、errbufのサイズ以下の非負の数値でなければならない。
regerror
のエラー文字列を収めるのに必要な
errbufの大きさを決めるために、errbufにnullを、
errbuf_sizeにゼロをセットしてregerror
を呼ぶことができる。
POSIXではregmatch_t
型の変数は同様の情報を保持しているが、
GNUのregisterと同一ではない(セクション Using Registersを参照)。
POSIXでregisterに関する情報を得るためには、regmatch_t
型の
pmatchを0以外の値でregexec
を呼ぶ。
これはその型の構造体のアドレスであり、`regex.h'で定義されている。
typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t;
セクション Using Registersを参照で説明されているマッチング関数がレジスタに
ストアする情報を、
regsをpmatchに、
regs->start[i]
を
pmatch[i]->rm_so
に、
regs->end[i]
を
pmatch[i]->rm_eo
に
置き換えること。
パターンバッファのallocated fieldを解放するには次の関数を使う。
void regfree (regex_t *preg)
pregは解放したいallocated fieldsを持つパターンバッファである。
regfree
はpregの allocated
フィールドと used
フィールド
に0をセットする。パターンバッファを解放した後では、マッチング関数
(セクション POSIX Matchingを参照)を
呼び出す前にはもう一度バッファ中の正規表現をコンパイルする必要がある
(セクション POSIX Regular Expression Compilingを参照)。
もし、プログラムをBerkeley UNIXとコンパチブルに書かなければ ならないのであれば、(Berkeley UNIXと同じインターフェースを 持っている)これらの関数を使う必要があるだろう。
Berkeley UNIXでは、与えられた正規表現の検索だけが可能であり、
マッチングをすることはできない。検索を行うために、まずはじめに
正規表現をコンパイルしなければならない。
そして、コンパイルをする前に、正規表現のシンタクスを自分の希望するものに
するためにre_syntax_options
(`regex.h'中で宣言されている
(セクション Regular Expression Syntaxを参照)という変数をセットしなければ
ならない。
正規表現をコンパイルするのには次の関数を使う。
char * re_comp (char *regex)
regexはnullで終端されている正規表現のアドレスである。
re_comp
は内部的なパターンバッファを使うので
一番最近に使ったコンパイル済みパターンバッファだけが使える。
つまり、すでにコンパイルされた正規表現を与えて実行したいと思ったとしても、
それがもっとも最近にコンパイルされたものでなければ
もう一回コンパイルしなければならない。という事である。
もしre_comp
をnull文字列(空文字列ではない)にして引数にして呼び出すと
パターンバッファを変更しない。
re_comp
は正規表現のコンパイルに成功すると0を返す。
コンパイルできない場合にはエラー文字列を返す。
re_comp
のエラーメッセージはre_compile_pattern
と同じである
(セクション GNU Regular Expression Compilingを参照)。
Berkeley UNIXでの検索の方法は
文字列の最初のキャラクタを探し、連続するポジションがマッチするものか
どうかを試すというものである。
一度re_comp
(セクション BSD Regular Expression Compilingを参照)
を使ってパターンをコンパイルすれば、Regexに対して
そのパターンを文字列から検索するということができる。
int re_exec (char *string)
stringはnullターミネートされた検索対象の文字列である。
re_exec
は成功すれば1、失敗すれば0を返す。
この関数は自動的にGNU fastmap (セクション Searching with Fastmapsを参照)を
使用する。