RE_FORMAT(7) | FreeBSD Miscellaneous Information Manual | 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 つの整数値 i と j が含まれる領域がアトムに続くと、 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 | xdigit |
これらは、 ctype(3) において定義されている文字クラスを表わしています。ロケールによっては、これら以外のものがあることがあります。文字クラスは、文字範囲の終了点として使うことは出来ません。
文字クラスに属する単一文字にマッチするために、‘ [[:class:]]
’のような角括弧式を使用することができます。逆に、特定のクラスに属さない任意の文字にマッチするためには、次のような、角括弧式の否定の演算子を使用します: ‘ [^[:class:]]
’。
角括弧式には、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
’にはマッチしません。
バグ
正規表現が 2 種類もあるのはへまなことです。 現在の IEEE Std 1003.2 (“POSIX.2”) 仕様では、‘ )
’は、マッチする‘ (
’がない場合に普通の文字として扱われることになっています。これは、言葉使い上の誤りの意図しない結果であり、変更される可能性があります。よって、この仕様に依存すべきではありません。
後方参照は、ひどいへまであり、効率的な実装をおこなう上で大きな問題を引き起こします。さらに、それらの定義は、どこかあいまいです。 (‘ a\(\(b\)*\2\)*d
’は、‘ abbbd
’にマッチするでしょうか ?) これらを使うのは、避けてください。
IEEE Std 1003.2 (“POSIX.2”) のケース非依存マッチの仕様は、あいまいです。上記での“ひとつのケースは、すべてのケースを表わす”という定義は、実装を行ったものの間では、正しい解釈として現在同意されているものです。
語の境界の構文は、信じられないほど醜いものです。
March 20, 1994 | FreeBSD |