EN JA
REGEX(3)
REGEX(3) FreeBSD Library Functions Manual REGEX(3)

名称

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

ライブラリ

Standard C Library (libc, -lc)

書式

#include < regex.h>

int
regcomp( regex_t * restrict preg, const char * restrict pattern, int cflags);

int
regexec( const regex_t * restrict preg, const char * restrict string, size_t nmatch, regmatch_t pmatch[restrict], int eflags);

size_t
regerror( int errcode, const regex_t * restrict preg, char * restrict errbuf, size_t errbuf_size);

void
regfree( regex_t *preg);

解説

これらのルーチンは IEEE Std 1003.2 (“POSIX.2”) 正規表現 (“RE”) を実装します。 re_format(7) を参照してください。 regcomp() 関数は、文字列として内部形式に書き込まれた RE (正規表現) をコンパイルします。 regexec() は文字列とその内部形式を照合し結果を報告します。 regerror() はエラーコードを人間の判読可能なメッセージに変形します。また、 regfree() は、RE の内部形式によって使用されるダイナミックに割り付けられたすべての記憶域を解放します。

ヘッダ < regex.h> は 2 つの構造体タイプ、コンパイルされた内部形式のため regex_t および照合の報告のための regmatch_t を宣言します。さらに、それは 4 つの関数、タイプ regoff_t および“ REG_”で始まる名前の多くの定数を宣言します。

regcomp() 関数は、 cflags 中のフラグに従って、 pattern (パターン) 文字列に含まれる正規表現をコンパイルし、 preg によって指された regex_t 構造体に結果が置かれます。 cflags 引数は 0 以上の次のフラグのビット毎の OR (論理和) です。

REG_EXTENDED
デフォルトである旧式の (“基本”) RE ではなく、現代的な (“拡張”) RE をコンパイルします。
REG_BASIC
これは 0 の同意語です。読みやすさを改善するために REG_EXTENDED に対応するものとして提供されます。
REG_NOSPEC
すべての特別の文字がオフであることを認識してコンパイルします。したがって、すべての文字は通常とみなされるので、“RE”はリテラル文字列です。これは IEEE Std 1003.2 (“POSIX.2”) と互換性がありますが、明記されていない拡張です。他のシステムに移植するつもりであるソフトウェアで注意して使用されるべきです。 REG_EXTENDEDREG_NOSPECregcomp() への同じ呼び出しで使用できません。
REG_ICASE
大文字/小文字の区別を無視するマッチングのためにコンパイルします。 re_format(7) を参照してください。
REG_NOSUB
何とマッチしたかではなく、成功か失敗かの報告のみに必要なマッチングのためにコンパイルします。
REG_NEWLINE
改行に反応するマッチングのためにコンパイルします。デフォルトでは、改行は RE あるいは文字列のいずれかで特別の意味がない完全に普通の文字です。このフラグで、‘ [^’角括弧式および‘ .’は改行と一致しません。‘ ^’アンカはその通常関数に加えて文字列中で任意の改行の後のヌル文字列と一致します。そして‘ $’アンカはその通常関数に加えて文字列中の任意の改行の前のヌル文字列と一致します。
REG_PEND
正規表現は、最初のヌル文字ではなく、 preg によって指される構造体の re_endp メンバによって指される文字の前でちょうど終了します。 re_endp メンバはタイプ const char * です。このフラグは、RE の中にヌル文字を含むことを許可します。これらは通常の文字とみなされます。これは IEEE Std 1003.2 (“POSIX.2”) と互換性がありますが、明記されていない拡張です。他のシステムに移植するつもりであるソフトウェアで注意して使用されるべきです。

成功する場合、 regcomp() は 0 を返し、 preg によって指される構造体を情報で埋めます。その構造体の ( re_endp 以外の) 1 つのメンバが公表されます。タイプ size_tre_nsub は、 ( REG_NOSUB フラグが使用された場合このメンバの値が未定義であることを除いて) RE の括弧に入れられたサブ表現の数を含んでいます。 regcomp() が失敗する場合、それは 0 でないエラーコードを返します。 診断 を参照してください。

regexec() 関数は eflags のフラグに従って、 preg によって指されるコンパイルされた RE と string を照合します。そして、 nmatch, pmatch および返された値を使用して結果を報告します。 RE は、 regcomp() の前の呼び出しによってコンパイルされなければなりません。コンパイルされた形式は、 regexec() の実行の間に変更されませんので、単一のコンパイルされた RE は複数のスレッドで同時に使用できます。

デフォルトでは、 string によって指されるヌル文字で終了する文字列は任意の終端の改行を差し引いてすべての行のテキストであるとみなされます。 eflags 引数は次のフラグの 0 個以上のビット毎の論理和 (OR) です。

REG_NOTBOL
文字列の最初の文字は行の始まりではありませんので、‘ ^’アンカはその前に一致してはなりません。これは、 REG_NEWLINE の下の改行の振る舞いに影響しません。
REG_NOTEOL
文字列を終了するヌル文字は行を終了しないので、‘ $’アンカはその前に一致してはなりません。これは、 REG_NEWLINE の下での改行の振る舞いに影響しません。
REG_STARTEND
nmatch の値にかかわらず文字列は string + pmatch[0]. rm_so から始まり、終端のヌル文字は string + pmatch[0]. rm_eo に位置するとみなされます。 (その位置にヌル文字が実際にある必要はありません)。 pmatchnmatch の定義に関しては、下記を参照してください。これは IEEE Std 1003.2 (“POSIX.2”) と互換性がありますが、明記されていない拡張です。他のシステムに移植するつもりであるソフトウェアで注意して使用されるべきです。 0 でない rm_soREG_NOTBOL を意味しないことに注意してください。 REG_STARTEND は、文字列の位置だけに影響し、マッチする方法には影響しません。

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

通常は、 regexec() は、成功すれば 0 を返し、失敗すれば 0 でないコード REG_NOMATCH を返します。例外的な状況で、他の 0 でないエラーコードが返されるかもしれません。 診断 を参照してください。

RE のコンパイルで REG_NOSUB が指定された場合、あるいは nmatch が 0 である場合、 regexec() は pmatch 引数を無視します (しかし REG_STARTEND が指定される場合に関しては、下記を参照してくだい)。そうでなければ、 pmatch はタイプ regmatch_tnmatch 構造体の配列を指します。前記の構造体は少なくともメンバ rm_so および rm_eo を持っています。それは、両方ともタイプ regoff_t (少なくとも off_tssize_t と同じ大きさの符号付き算術タイプ) で、サブストリングの最初の文字のオフセットとサブストリングの終りの後の最初も文字のオフセットをそれぞれ含んでいます。オフセットは regexec() へ与えられた string 引数の始めから測定されます。空のサブストリングは、空のサブストリングに続く文字を示す、等しいオフセットによって表示されます。

pmatch 配列の 0 番目のメンバは string のどのサブストリングが全 RE によって一致したか示すために書き入れられます。残りのメンバは、RE の括弧で囲まれたサブ表現によってどのサブストリングが一致したことを報告します。メンバ i は、左から右へ、RE 中の左括弧の順序で数えられた (1 から開始して) サブ表現でサブ表現 i を報告します。マッチに全く参加しなかったサブ表現か、あるいは RE (すなわち、 i > preg-> re_nsub) に存在しないサブ表現のいずれかに対応する) 配列の未使用エントリは rm_so および rm_eo の両方は -1 に設定されています。サブ表現がマッチに数回参加した場合、報告されたサブストリングはそれが一致した最後のサブストリングです。 (注意、項目中の例として、 RE ‘ (b*)+’が‘ bbb’とマッチする時、括弧で囲まれたサブ表現は、3 つの‘ b’の各々と、最後の‘ b’に続く空の文字列の無限の数と一致します、したがって、報告されたサブストリングは空のうちの 1 つです。)

REG_STARTEND が指定される場合、 pmatchREG_STARTEND のための入力オフセットを保持するために、少なくとも 1 つの regmatch_t ( nmatch が 0 であるか REG_NOSUB が指定されたとしても) を指さなければなりません。出力のための使用は、 nmatch によってまだ完全に制御されます。 nmatch が 0 であるか、 REG_NOSUB が指定された場合、 pmatch[0] の値は成功した regexec() によって変更されません。

regerror() 関数は、 regcomp() あるいは regexec() のいずれかからの 0 でない errcode を人間が判読可能な印刷可能なメッセージにマップします。 pregNULL でない場合、エラーコードは preg によって指される regex_t の使用から発生するべきです。また、もしエラーコードが regcomp() から生じた場合、それは regex_t を使用して、最近の regcomp() からの結果となるはずです。 ( regerror() は regex_t からの情報を使用して、もっと詳細なメッセージを供給することができるかもしれません。) regerror() 関数は、多くても errbuf_size バイトの長さの制限 (ヌル文字を含んで) がある、 errbuf に指されるバッファにヌル文字で終了したメッセージを置きます。全体のメッセージが収まらない場合、終端のヌル文字の前に収まるだけの量が供給されます。どんな場合も、返される値は (終端のヌル文字を含んだ) 全体のメッセージを保持するために必要なバッファのサイズです。 errbuf_size が 0 である場合、 errbuf は無視されますが、返り値はまだ正確です。

regerror() に与えられた errcodeREG_ITOA で最初に論理和 (OR) される場合、結果の“メッセージ”は、その説明ではなく、(例えば“ REG_NOMATCH”など) エラーコードの印刷可能な名前です。 errcodeREG_ATOI である場合、 pregNULL でないものとします。また、それが指す構造体の re_endp メンバはエラーコードの印刷可能な名前を指さなければなりません。この場合、 errbuf 中の結果は (名前が認識されない場合、0 の) エラーコードの数値の 10 進数です。 REG_ITOAREG_ATOI は主としてデバッグ機能を目的にしています。それらは IEEE Std 1003.2 (“POSIX.2”) と互換性がありますが、明記されていない拡張です。他のシステムに移植するつもりであるソフトウェアで注意して使用されるべきです。それらはまた、実験的であると考えられ、変更の可能性があることに注意してください。

regfree() 関数は、 preg によって指されるコンパイルされた RE に関連した、すべてのダイナミックに割り付けられた記憶域を解放します。残りの regex_t はもはや有効なコンパイルされた RE ではありません。また、 regexec() か regerror() にそれを供給する結果は不確定です。

これらの関数のどれも定数のテーブルを除いてグローバル変数を参照しません。引数が安全な場合、複数のスレッドからの使用にとってすべて安全です。

実装の選択

“未定義”であると明白に書くことか、または RE 文法によって禁止されているそれらの長所によってのいずれかで、 IEEE Std 1003.2 (“POSIX.2”) は実装者に委ねられている多くの決定があります。この実装は次のようにそれらを扱います。

大文字小文字を区別しないマッチの定義の議論に関しては、 re_format(7) を参照してください。

メモリが制限された場合を除いて、 RE の長さに特別の制限はありません。メモリ使用法は、境界のある反復を除いて、RE サイズにだいたい線形で、 RE 複雑さに大部分は無関心です。ほとんどのシステムのメモリ不足を実行するそれらを使用する短い RE に関しては、 バグ を参照してください。

IEEE Std 1003.2 (“POSIX.2”) (旧式の[“基本”] RE でのみ、そのような魔法の意味が生じます) によって魔法の意味を特に与えられたもの以外のバックスラッシュ文字は、通常の文字とみなされます。

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

等価クラスは角括弧表現の範囲を開始したり終了することができません。 1 つの範囲の終了点は別のものを開始することができません。

境界のある反復で反復数の制限である RE_DUP_MAX, は 255 です。

反復演算子 (‘ ?’, ‘ *’, ‘ +’, あるいは境界) は別の反復演算子に続くことはできません。反復演算子は表現またはサブ表現を開始したり、‘ ^’または‘ |’の後に続けることはできません。

|’は (サブ) 表現の最初または最後にあるいは別の‘ |’の後に現われることはできません。すなわち、‘ |’のオペランドは空のサブ表現にすることはできません。空の括弧で囲まれたサブ表現‘ ()’は、有効で、空の (部分) 文字列と一致します。空の文字列は正当な RE ではありません。

数字が後続する‘ {’は境界のある反復のための境界の始めとみなされます。それは境界のためのシンタックスが続かなければなりません。数字が続かない‘ {’は通常の文字とみなされます。

旧式の (“基本”) RE の中のサブ表現を開始して終了する‘ ^’および‘ $’は、通常の文字ではなくアンカです。

診断

regcomp() および regexec() の 0 でないエラーコードは次の通りです。

REG_NOMATCH
regexec() 関数は一致に失敗しました
REG_BADPAT
無効の正規表現
REG_ECOLLATE
無効の照合要素
REG_ECTYPE
invalid character class 無効の文字クラス
REG_EESCAPE
\’をエスケープできない文字に適用
REG_ESUBREG
無効のバックレファレンス番号
REG_EBRACK
角括弧‘ [ ]’は釣り合わない
REG_EPAREN
丸括弧‘ ( )’は釣り合わない
REG_EBRACE
中括弧‘ { }’は釣り合わない
REG_BADBR
{ }’内の無効の反復数
REG_ERANGE
[ ]’内の無効の文字範囲
REG_ESPACE
メモリが不足した
REG_BADRPT
?’, ‘ *’または‘ +’オペランドは無効
REG_EMPTY
空の (サブ) 表現
REG_ASSERT
起こり得ない - バグを見つけました
REG_INVARG
無効の引数、例えば負の長さの文字列
REG_ILLSEQ
不正なバイトシーケンス (悪いマルチバイト文字)

関連項目

grep(1), re_format(7)

IEEE Std 1003.2 (“POSIX.2”), sections 2.8 (Regular Expression Notation) および B.5 (C Binding for Regular Expression Matching)。

歴史

最初は Henry Spencer によって書かれました。 4.4BSD 配布へ含めるために変更されました。

バグ

これは既知の欠陥があるアルファリリースです。問題を報告してください。

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

regexec() 関数の性能は貧弱です。これは後のリリースで改善するでしょう。 0 を越える nmatch 引数は高価です。 1 を越える nmatch はより悪くなります。 regexec() 関数は、バックリファレンスが重く高価であることを除いて、RE の複雑さに大部分は無関心です。 RE の長さは重要です。特に、ほとんどの特殊文字をおよそ 2 倍と数えて、 RE の長さを約 30 文字未満に維持すれば速度が速くなります。

数が大きいか、境界のある反復が入れ子にされる場合、 regcomp() 関数は、時間と空間で高価なマクロの拡張によって境界のある反復を実装しています。‘ ((((a{1,100}){1,100}){1,100}){1,100}){1,100}’のような RE は (結局) ほとんどのどんな既存のマシンでもスワップスペース不足となります。

原因不明のエラー条件のレスポンスで疑わしい問題があります。明らかに、ある種類の内部オーバフローは本当に大きい RE によってか、複数の入れ子になった境界のある反復によって生成されたある種類の内部オーバフローは、おそらく上手に操作できません。

IEEE Std 1003.2 (“POSIX.2”) の誤りによって、‘ )’は一致しない‘ (’の前に存在するときのみ特別の文字であるので、‘ a)b’のようなものは正しい RE です。仕様が修正されるまで、これは修正することができません。

標準のバックリファレンスの定義は曖昧です。例えば、‘ a\(\(b\)*\2\)*d’は‘ abbbd’と一致しますか。標準が明確にされるまで、そのような場合の振る舞いを頼みにすべきでありません。

ワード境界マッチングの実装は、クラッジ (kludge) が少しあります。また、バグはワード境界マッチングおよびアンカの組み合わせに潜んでいるかもしれません。 (訳注) クラッジ: 便宜的にトリックを使って問題を一時的に解決すること。

ワード境界のマッチングは、マルチバイトロケールで適切に動作していません。

August 17, 2005 FreeBSD