REGEX

Section: C Library Functions (3)
Updated: March 20, 1994
索引 jman
 

索引

名称

regcomp, regexec, regerror, regfree - 正規表現ライブラリ  

索引

書式

#include <sys/types.h>
#include <regex.h>
int regcomp(regex_t *preg, const char *pattern, 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);
 

索引

解説

このルーチンは、POSIX 1003.2 正規表現(``RE'')を実現しています。 re_format(7) を参照してください。 regcomp は、内部フォームにストリングとして書き込まれた RE をコンパイルします。 regexec は、その内部フォームをストリングと突き合わせて結果を報告します。 regerror は、エラーコードを人が判読できるメッセージに変換します。 regfree は、RE の内部フォームで使用される、 ダイナミックに割り振られた記憶域を解放します。

ヘッダ <regex.h> は、コンパイルされた内部フォーム用の regex_t, および突き合わせの報告用の regmatch_t という、2 つの構造体タイプを宣言します。4 つの関数、タイプ regoff_t, 名前が ``REG_'' で始まる定数の数も宣言します。

Regcomp は、 cflags のフラグに従って、 pattern ストリングに含まれる正規表現をコンパイルし、 preg が指す regex_t 構造体に結果を配置します。 cflags は、ゼロ個以上の以下のフラグでビットワイズ論理和を取ったものです。

REG_EXTENDED
デフォルトの古い ( ``基本'' ) RE の代わりに、新しい ( ``拡張'' ) RE を コンパイルします。
REG_BASIC
0 のシノニムです。 REG_EXTENDED に対して提供されたもので、読みやすさを改善します。
REG_NOSPEC
すべての特殊文字が無効になっていることを認識して コンパイルします。すべてのキャラクタは通常文字とみなされるので、 ``RE'' はリテラルストリングになります。これは、POSIX 1003.2 と 互換性があるが指定されていないエクステンションです。 他のシステムに移植することを目的としたソフトウェアでは 注意して使用してください。REG_EXTENDED と REG_NOSPEC は、 regcomp の呼び出しで同時には使用できません。
REG_ICASE
大文字と小文字を区別しないマッチング用にコンパイルします。 re_format(7) を参照してください。
REG_NOSUB
一致したものではなく、問題の有無のレポートのみが必要な マッチング用にコンパイルします。
REG_NEWLINE
改行を考慮するマッチング用にコンパイルします。 デフォルトの場合、改行は、RE とストリングで特殊な意味がない、完全な 通常文字です。このフラグを使用すると、ブランケット `[^' と `.' は改行と 一致しなくなります。アンカ `^' は、通常関数に加え、ストリングの改行の 後ろにある NULL ストリングと一致するようになります。アンカ `$' は、 通常関数に加え、ストリングの改行の前にある NULL ストリングと 一致するようになります。
REG_PEND
最初の NULL ではなく、 preg が指す構造体の re_endp メンバが指すキャラクタの直前で正規表現が終わるようになります。 re_endp メンバのタイプは const char * です。このフラグは、RE に NULL が含まれることを許可します。 この NULL は、通常文字とみなされます。これは、POSIX 1003.2 と 互換性があるが指定されていないエクステンションです。他のシステムへの移植を 目的としたソフトウェアでは注意して使用してください。

問題がない場合、 regcomp は 0 を戻し、 preg が指す構造体にデータを入れます。 この構造体の 1 つのメンバ ( re_endp 以外 ) は公表されます。 size_t タイプの re_nsub には、RE の括弧で囲まれたサブ表現の数が入ります ( REG_NOSUB フラグを 使用した場合、このメンバの値は不定になります ) 。 regcomp でエラーが発生すると、ゼロ以外のエラーコードが戻されます。診断を 参照してください。

regexec は、 eflags のフラグに従って、 preg が指すコンパイル済み RE を string と突き合わせ、 nmatch, pmatch, 戻り値を使用して結果を報告します。RE は、これ以前に regcomp を呼び出してコンパイルしておく必要があります。 コンパイルされたフォームは、 regexec を実行しても変更されないので、1 つのコンパイル済み RE を 複数のスレッドで同時に使用できます。

デフォルトの場合、 string が指す、NULL で終了するストリングは、 ライン全体から最後の改行を除いたテキストとみなされます。 eflags 引数は、ゼロ個以上の以下のフラグでビットワイズ論理和を取ったものです。

REG_NOTBOL
ストリングの最初のキャラクタがラインの最初ではないので、`^' アンカが その前で一致する必要はありません。REG_NEWLINE の改行の動作は影響されません。
REG_NOTEOL
ストリングを終了する NULL がラインを終了しないので、`$' アンカが その前で一致する必要はありません。REG_NEWLINE の改行の動作は影響されません。
REG_STARTEND
nmatch の値に関係なく、ストリングが string + pmatch[0].rm_so で始まり、最後の NULL が string + pmatch[0].rm_eo に配置されている ( その場所に NULL が実際に存在する必要はない ) と みなされます。 pmatchnmatch の定義については、下記を参照してください。 これは、POSIX 1003.2 と互換性があるが指定されていないエクステンションです。 他のシステムへの移植を目的としたソフトウェアでは注意して使用してください。 rm_soがゼロ以外であっても、 REG_NOTBOL が暗示されることはありません。 REG_STARTEND はストリングの位置のみに影響し、マッチング方法には 影響しません。

RE かその一部が string のサブストリングと一致する状況で一致するものについては、 re_format(7) を参照してください。

通常の場合、 regexec は問題がないと 0 を戻し、問題があるとゼロ以外のコード REG_NOMATCH を 戻します。例外的な状況では、ゼロではない、これ以外の エラーコードが戻されることがあります。診断を参照してください。

RE のコンパイルで REG_NOSUB を指定した場合、または nmatch が 0 である場合、 regexecpmatch 引数を無視します ( REG_STARTEND を指定した場合については下記参照 ) 。 その他の場合、 pmatchregmatch_t タイプの nmatch 構造体の配列を指します。このような構造体には、 サブストリングの第 1 キャラクタのオフセットを含む rm_so 、およびサブストリングの最後の後ろにある第 1 キャラクタのオフセットを含む rm_eo というメンバが最低でも必要です。 どちらもタイプは regoff_t ( 最低でもサイズが off_tssize_t である、符号付き算術タイプ ) です。オフセットは、 regexec に指定した string 引数の最初から計測されます。空のサブストリングは、空のサブストリングに続く キャラクタを示す、等しいオフセットで表現されます。

pmatch 配列の 0 番目のメンバには、RE 全体で一致した、 string のサブストリングが入ります。残りのメンバは、RE の括弧で囲まれたサブ表現で 一致したサブストリングを報告します。メンバ i は、RE の左括弧の次数を左から右に 1 から数えたサブ表現で、サブ表現 i を報告します。突き合わせにまったく関係しなかったサブ表現か RE に存在しない サブ表現 ( つまり、i > preg->re_nsub) に対応する、 配列の未使用エントリでは、 rm_sorm_eo の 両方が -1 に設定されています。サブ表現が突き合わせに複数回関係した場合は、 一致した最後のサブストリングが報告されます ( RE `(b*)+' が `bbb' と 一致する場合、括弧に囲まれたサブ表現は、3 つそれぞれの `b' 、 および最後の `b' に続く無限の空ストリングと一致するため、 報告されるサブストリングは空のうちの 1 つになります ) .

REG_STARTEND を指定した場合、 pmatch は最低でも 1 つの regmatch_t を指し ( nmatch が 0 であるか、REG_NOSUB を指定した場合でも )、 REG_STARTEND の入力オフセットを保持する必要があります。出力での使用は、 nmatch で完全に制御されます。 nmatch が 0 である場合、または REG_NOSUB を指定した場合、 pmatch[0] の値は、 regexec で問題が発生しなければ変更されません。

regerror は、 regcompregexec のゼロでない errcode を人間が判読可能で出力できるメッセージにマップします。 preg が NULL 以外である場合、エラーコードは、 preg が指す regex_t の使用から発生します。エラーコードが regcomp からのものである場合、エラーコードは、その regex_t を使用して 最近実行した regcomp の結果となります (regerror は、 regex_t の情報を使用してより詳細なメッセージを提供することがあります ) 。 regerror は、NULL で終わるメッセージを errbuf が指すバッファに配置します。NULL を含めたメッセージの長さは、最大で errbuf_size バイトに制限されます。 メッセージ全体が収まらない場合は、最後の NULL の前で収まる部分までが 提供されます。どのような場合でも、戻り値は、最後の NULL も含めた、 メッセージ全体を保持するのに必要なバッファサイズになります。 errbuf_size が 0 である場合、 errbuf は無視されますが、戻り値は正確です。

regerror に与えられた errcode と REG_ITOA の論理和を最初に取ると、作成される ``メッセージ'' は、 エラーコードの説明ではなく、``REG_NOMATCH'' など、 エラーコードの出力可能な名前になります。 errcode が REG_ATOI である場合、 preg は NULL 以外で、これが指す構造体の re_endp メンバは、エラーコードの出力可能な名前を指す必要があります。この場合、 errbuf の結果は、エラーコードの数値の十進数になります ( 名前が 認識されない場合は 0 ) 。 REG_ITOA と REG_ATOI は、主にデバッグを目的としたものです。 これは、POSIX 1003.2 と互換性があるが指定されていない エクステンションです。他のシステムへの移植を目的としたソフトウェアでは 注意して使用してください。また試験的なものとみなされているので、 変更されることがあることにも注意してください。

regfree は、 preg が指すコンパイル済み RE に関連する、ダイナミックに 割り振られた記憶域を解放します。残った regex_t は有効なコンパイル済み RE ではないので、 regexecregerror でこれを使用しても結果は不定になります。

このすべての関数は、目次を除くグローバル変数を参照しません。引数が 安全である場合、複数のスレッドで使用しても安全です。  

索引

実装における選択

1003.2 には、``未定義'' と明言する形で、または RE の文法で 禁止されているという形で、システム設計者にゆだねている未決定事項が 数多くあります。このシステムでは、この未決定事項を以下のように 扱っています。

大文字と小文字を区別するマッチングの定義については、 re_format(7) を参照してください。

メモリの制限を除けば、RE の長さに制限はありません。メモリの使用量は RE のサイズにだいたい比例しており、制限付きの反復を除いて、RE の複雑さに 大きく左右されることはありません。ほとんどのシステムでメモリが不足する、 反復を使用した短い RE については、バグを参照してください。

1003.2 で特別な意味 ( このような特別な意味は、 古い [``basic''] RE のみにあります ) が与えられているもの 以外のバックスラッシュキャラクタは、通常文字とみなされます。

一致しない [ は REG_EBRACK エラーです。

等価クラスは、括弧で囲まれた表現の範囲を始めたり 終了したりできません。ある範囲の終了点が、他の範囲の 開始点になることはありません。

制限付き反復の反復数の制限である RE_DUP_MAX は 255 です。

反復演算子 (?, *, +, 制限) に別の反復演算子を 続けることはできません。反復演算子で表現やサブ表現を始めたり、 `^' か `|' の後に反復演算子を続けたりすることはできません。

表現やサブ表現の最初か最後に `|' を使用したり、`|' の後に 別の `|' を使用したりすることはできません。たとえば、`|' のオペランドを 空のサブ表現にすることはできません。括弧で囲まれた空のサブ表現 `()' は 許可されており、空のストリングかサブストリングと一致します。空のストリング は、適切な RE ではありません。

後に数字が続く `{' は、制限付き反復の制限の始まりとみなされます。 この場合は、制限のシンタックスに従う必要があります。後に数字が 続かない `{' は、通常文字とみなされます。

古い ( ``基本'' ) RE のサブ表現の開始と終了を表す `^' と `$' はアンカ であり、通常文字ではありません。  

索引

関連項目

grep(1), re_format(7) POSIX 1003.2, sections 2.8 (Regular Expression Notation) および B.5 (C Binding for Regular Expression Matching)  

索引

診断

以下は、 regcompregexec のゼロでないエラーコードです。


REG_NOMATCH    regexec() の一致でエラーが発生
REG_BADPAT     正規表現が正しくない
REG_ECOLLATE   照合するエレメントが正しくない
REG_ECTYPE     キャラクタクラスが正しくない
REG_EESCAPE    エスケープ以外のキャラクタに \ が付いている
REG_ESUBREG    バックリファレンス番号が正しくない
REG_EBRACK     括弧 [ ] の数が合わない
REG_EPAREN     括弧 ( ) の数が合わない
REG_EBRACE     括弧 { } の数が合わない
REG_BADBR      { } の反復数が正しくない
REG_ERANGE      [ ] のキャラクタ範囲が正しくない
REG_ESPACE     メモリ不足
REG_BADRPT      ?, *, + オペランドが正しくない
REG_EMPTY      空の表現かサブ表現
REG_ASSERT     ``ありえない''、つまりバグ
REG_INVARG     引数が正しくない ( 負の長さのストリングなど )
 

索引

歴史

最初の作者は Henry Spencer です。 の配布に含めるために変更されました。  

索引

バグ

アルファリリースであるため、欠陥のあることが知られています。 問題がある場合は報告してください。

機能的なバグとして知られているものに、国際化のシステムが 不完全であるということがあります。 1003.2 のデフォルトロケールが常に 仮定されるので、そのロケールの照合エレメントなどしか使用できません。

バックリファレンスコードは微妙で、複雑な場合はその正確さに疑問が 残ります。

regexec のパフォーマンスは低くなっています。後のリリースでは 改善されますが、 nmatch が 0 を越えるとコストがかかり、 1 を越えると状況はさらに悪化します。 regexec は、バックリファレンスに多くのコストがかかる場合を除き、 RE の複雑さには大きく影響されません。問題は RE の長さで、 特殊文字を 2 倍として計算し、RE の長さを約 30 キャラクタに 収めると、処理は速くなります。

regcomp は、マクロ拡張で制限付き反復を実現しています。制限付き反復には、 数が大きい場合、または制限付き反復がネストされている場合、長い 時間と多くのスペースが必要です。たとえば `((((a{1,100}){1,100}){1,100}){1,100}){1,100}' のような RE では、最終的にほとんどのマシンでスワップスペースが不足します。

はっきりとしないエラー条件へのリスポンスにも問題があるようです。 非常に大きな RE か複雑にネストした制限付き反復で引き起こされる、特定の内部 オーバフローは、適切に処理されないことがあります。

1003.2 の誤りにより、一致しない `(' が前にある場合にのみ `)' が 特殊文字になるので、`a)b' のようなものが正しい RE になってしまいます。 この問題は、仕様が修正されるまで修正されません。

バックリファレンスに関する、標準の定義は曖昧になっています。 たとえば `a\(\(b\)*\2\)*d' が `abbbd' と一致してしまうのです。標準が 明確になるまで、このような場合の動作は信頼すべきではありません。

ワード境界マッチングのシステムは多少あいまいで、ワード境界マッチング とアンカの組み合わせにはバグが潜んでいる可能性があります。


 

索引

Index

名称
書式
解説
実装における選択
関連項目
診断
歴史
バグ

jman



Time: 07:07:05 GMT, January 12, 2009