スポンサーリンク

REGEX

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

名称

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’ と一致してしまうのです。標準が明確になるま で、このような場合の動作は信頼すべきではありません。

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

スポンサーリンク