スポンサーリンク

RE_FORMAT(7) FreeBSD 多方面の情報マニュアル RE_FORMAT(7)

名称

re_format − POSIX 1003.2 正規表現

解説

IEEE Std 1003.2 (‘‘POSIX.2’’) において定義されているように、正規表現 (‘‘RE’’) には 2 つの形式があります。ひとつは現代正規表現 (大雑把にいうと egrep(1) で使用されているもので、1003.2 での ‘‘拡張’’ 正規表現) で、もう ひとつは旧式正規表現 (これも大雑把には ed(1) で使用されているもの で、1003.2 での ‘‘基本’’ 正規表現) です。旧式正規表現は大抵の場合いくつか の古くからあるプログラムでの旧バージョンとの互換性のために存在していま す。これについては最後に説明します。 IEEE Std 1003.2 (‘‘POSIX.2’’) は正規 表現の構文と意味のいくつかの部分を明確に定めないままにしています。他の IEEE Std 1003.2 (‘‘POSIX.2’’) の実装とは完全な互換性がないかもしれないこ れらの部分については、‘‡’ によって印をつけて示します。

正規表現 (現代正規表現) はひとつ‡もしくはそれ以上の空でない‡ 枝 (branch) を ‘|’ によって区切ったものです。いずれかの枝にマッチすると正規表現はマッ チします。

枝はひとつ‡以上の ピース (piece) が結合されたものです。枝は最初のピース、 次のピース...とすべてがマッチしたものにマッチします。

ピースは アトム (atom) 、もしくはそれに単一の ‡ ‘*’, ‘+’, ‘?’ か 領域 (bound) のいずれかが続いたものです。アトムに ‘*’ が続いたものは、そのアト ムの 0 個以上のシーケンスにマッチします。アトムに ‘+’ が続いたものは、そ のアトム 1 個以上のシーケンスにマッチします。アトムに ‘?’ が続いたもの は、そのアトムの 0 個か 1 個のシーケンスにマッチします。

領域は ‘{’ で始まり、符号なしの 10 進数の整数が続き、その次に ‘,’ が続く ことがあり、またその次にもうひとつ符号なしの 10 進数の整数が続くことがあ り、最後には常に ‘}’ が続きます。ここでの整数は 0 から RE_DUP_MAX (255‡) の範囲 (これらの数値を含む) でなくてはならず、数値が 2 つある場合は、最初 のものは 2 番目のもの以下でなければなりません。ひとつの整数値 i が含まれ コンマが含まれない領域がアトムに続くと、アトムがちょうど i 個のシーケンス にマッチします。ひとつの整数値 i とコンマが含まれる領域がアトムに続くと、 i 個以上のアトムのシーケンスにマッチします。 2 つの整数値 ij が含まれ る領域がアトムに続くと、 i 個以上 j 個以下のアトムからなるシーケンスに マッチします。

アトムは次のいずれかです: ‘()’ に囲まれた正規表現 (その正規表現にマッ チ)、 ‘()’ の空のセット (ヌルストリングにマッチ)‡、 角括弧式 (下記参照)、 ‘.’ (任意の 1 文字にマッチ)、 ‘^’ (行の先頭のヌルストリングにマッチ)、 ‘$’ (行の末尾のヌルストリングにマッチ)、 ‘\’ とそれに続く ‘^.[$()|*+?{\’ の内のどれか 1 文字 (それらの通常の扱いでの文字にマッチ)、 ‘\’ とそれに続 くその他の文字‡ (それらの通常の扱いでの文字にマッチ、 ‘\’ がない場合と同 様‡)、もしくはその他に何も指定されていない文字 (その文字にマッチ)。 ‘{’ に数字以外の文字が続くものは通常の文字であり、領域の開始とはなりません‡。 ‘\’ で終了する正規表現は規則違反となります。

角括弧式 (bracket expression) とは ‘[]’ で囲まれた文字のリストです。通常 はリスト中のどれか 1 文字にマッチします (下記を除く)。リストの最初が ‘^’ で始まる場合、リストの残りの文字 でない 1 文字にマッチします (下記を除 く)。リスト中の 2 文字が ‘-’ で分割されている場合は、これら 2 文字の 範囲 (その 2 文字を含む) にある文字の省略形となり、例えば ASCII では ‘[0-9]’ は 10 進数数字にマッチします。 ‘a-c-e’ のように 2 つの文字範囲がひとつの 文字を共有することはできません‡。文字範囲は文字コードの配列に非常に依存し ており、移植性の良いプログラムを書くにはこれに頼ることを避けるのが賢明で しょう。

リスト中に文字 ‘]’ を含めるには、これを最初の文字にする (もしくは ‘^’ に 続ける) ようにします。文字 ‘-’ を含めるには、これを最初もしくは最後の文字 にするか、文字範囲の終了文字とします。文字 ‘-’ を文字範囲の開始文字とする には、これを連続要素とするために ‘[.’ と ‘.]’ で括ります (下記参照)。これ らと ‘[’ を使用したいくつかの組合せの例外を除いて、 ‘\’ を含むすべての他 の特殊文字は角括弧式の中ではそれらの特殊な作用は無効となります。

角括弧式の中では、連続要素 (文字、1 文字のように扱われる複数文字からなる シーケンス、またはそれら連続シーケンスの名称) は、 ‘[.’ と ‘.]’ で括ら れ、その連続要素の文字のシーケンスの意味となります。このシーケンスは角括 弧式のリストのひとつの要素となります。複数文字からなる連続要素を含む角括 弧式はこのように 1 文字以上のものにマッチすることができます。例えば、連続 シーケンスが連続要素として ‘ch’ を含む場合、正規表現 ‘[[.ch.]]*c’ は ‘chchcc’ の最初の 5 文字にマッチします。

角括弧式の中では、 ‘[=’ と ‘=]’ で囲まれた連続要素はひとつの等価クラスで あり、それ自身を含むすべての連続要素の文字のシーケンスを示しています。 ( もしその他に等価な連続要素がない場合は、それはそれを囲うものが ‘[.’ と ‘.]’ であるもののように扱われます。) 例えば、 ‘x’ と ‘y’ が等価クラスのメ ンバである時、 ‘[[=x=]]’ と ‘[[=y=]]’ と ‘[xy]’ はすべて同じ意味を持ちま す。等価クラスは文字範囲の終了点とすることはできません‡。

角括弧式の中では、 ‘[:’ と ‘:]’ で囲まれた 文字クラスの名称はそのクラスに 属するすべての文字のリストを表わします。標準の文字クラスの名称には次のも のがあります。

alnum digit punct
alpha graph space
blank lower upper
cntrl print xdigit

これらは ctype(3) において定義されている文字クラスを表わしています。ロ ケールによってはこれら以外のものがあることがあります。文字クラスは文字範 囲の終了点として使うことは出来ません。

角括弧式には 2 つの特殊なケース‡があります。角括弧式 ‘[[:<:]]’ と ‘[[:>:]]’ はそれぞれ単語の開始および終了点におけるヌルストリングにマッチ します。単語は単語文字が前にも後にも付加されない単語文字のシーケンスとし て定義されます。単語文字は alnum (アルファベットと数字) 文字 ( ctype(3) で定義されているように) か下線文字です。これは拡張して定義されているもの で、 IEEE Std 1003.2 (‘‘POSIX.2’’) に互換性はありますが、指定はされていま せん。この拡張はソフトウェアにおいては、他のシステムへの移植性をよく考え て使うべきです。

与えられた文字列の複数のサブストリング (文字列の一部) に、ある正規表現が マッチ可能な場合、その正規表現は文字列の中で最初に現れたものにマッチしま す。もし正規表現が同じ位置に現れた複数のサブストリングにマッチする場合 は、最も長いものにマッチします。サブ式 (subexpression - 式の一部) も最も 長いサブストリングにマッチしますが、マッチ全体が最も長くなるように、また 正規表現中で先に開始しているサブ式が遅く開始しているものより高い優先度を もつような条件があります。高いレベルのサブ式はこのため低いレベルの部品的 なサブ式より高い優先度を持ちます。

マッチの長さは連続要素ではなく、文字数で計られます。ヌルストリングは全く マッチしないものよりは長いものであると考えられます。例えば、 ‘bb*’ は ‘abbbc’ の 3 つの真中の文字にマッチし、 ‘(wee|week)(knights|nights)’ は ‘weeknights’ の 10 個すべての文字にマッチし、 ‘(.*).*’ が ‘abc’ にマッチ する時には、括弧で囲まれたサブ式は 3 つすべての文字にマッチします。そして ‘(a*)*’ が ‘bc’ にマッチする時には、正規表現全体と括弧で囲まれたサブ式の 両方がヌルストリングにマッチします。

ケース (大文字/小文字) 非依存マッチが指定された場合、アルファベットから ケースの区別がすべて消え去ったような効果があります。ケースが複数あるアル ファベットが角括弧式の外に通常の文字として現れた時、それは事実上すべての ケースを含む角括弧式 (たとえば ‘x’ は ‘[xX]’ に) に変換されます。角括弧式 の中に現れたときは、その文字の異なるケースがその角括弧式に追加されます。 すなわち ‘[x]’ は ‘[xX]’ となり、また ‘[^x]’ は ‘[^xX]’ となります。

正規表現の長さは特に制限は設けられていません‡。プログラムに移植性を持たせ たい場合は正規表現は 256 バイトにとどめるべきでしょう。 256 バイトを越え る正規表現の受理を拒否するにもかかわらず、 POSIX 準拠であるとする実装があ りうるからです。

旧式 (‘‘基本’’) 正規表現はいくつかの点で異なっています。 ‘|’ は通常の文字 であり、これらの機能の等価なものは存在しません。 ‘+’ や ‘?’ は通常の文字 であり、それらの機能は領域を用いて表されます (それぞれ ‘{1,}’ または ‘{0,1}’) 。また、現代正規表現の ‘x+’ は ‘xx*’ と等価であることに注意して 下さい。領域の区切り文字は ‘\{’ と ‘\}’ であり、 ‘{’ と ‘}’ は通常の文字 として扱われます。ネストしたサブ式での括弧は ‘\(’ と ‘\)’ であり、 ‘(’ と ‘)’ は通常の文字となります。 ‘^’ は正規表現の先頭、もしくは‡ 括弧で囲まれ たサブ式の先頭を除いて通常の文字となり、 ‘$’ は正規表現の末尾、もしくは‡ 括弧で囲まれたサブ式の末尾を除いて通常の文字となり、 ‘*’ はもしこれが正規 表現の先頭、もしくは括弧で囲まれたサブ式の先頭 (か、先頭の ‘^’ のあと) に 現れると通常の文字となります。最後にひとつ新しい型のアトム - 後方参照があ ります。 ‘\’ に 0 でない 10 進数 d が続いたものは、 d 番目の括弧で囲まれ たサブ式によってマッチする文字の同じシーケンスにマッチします (開き括弧の 位置によって左から右へサブ式に番号を付けます)。すなわち ‘\([bc]\)\1’ は ‘bb’ や ‘cc’ にマッチしますが、 ‘bc’ にはマッチしません。

関連項目

regex(3)

       Regular Expression Notation,                                      IEEE Std,                                                  1003.2,                                                            section 2.8.

バグ

正規表現が 2 種類もあるのはへまなことです。

現在の IEEE Std 1003.2 (‘‘POSIX.2’’) 仕様では ‘)’ はマッチする ‘(’ がない 場合に普通の文字として扱われることになっています。これは言葉使い上の誤り の意図しない結果であり、変更される可能性があります。よって、この仕様に依 存すべきではありません。

後方参照はひどいへまであり、効率的な実装をおこなう上で大きな問題を引き起 こします。さらに、それらの定義はどこかあいまいです。( ‘a\(\(b\)*\2\)*d’ は ‘abbbd’ にマッチするでしょうか ?) これらを使うのは避けてください。

IEEE Std 1003.2 (‘‘POSIX.2’’) のケース非依存マッチの仕様はあいまいです。 上記での ‘‘ひとつのケースはすべてのケースを表わす’’ という定義は実装を 行ったものの間では正しい解釈として現在同意されているものです。

語の境界の構文は信じられないほど醜いものです。

FreeBSD 10.0 March 20, 1994 FreeBSD 10.0

スポンサーリンク