鬼車 正規表現     2004/11/10

使用文法: ONIG_SYNTAX_RUBY (既定値)


1. 基本要素

  \       退避修飾 (エスケープ)  正規表現記号の有効/無効の制御
  |       選択子
  (...)   式集合   (グループ)
  [...]   文字集合 (文字クラス)


2. 文字

  \t           水平タブ        (0x09)
  \v           垂直タブ        (0x0B)
  \n           改行            (0x0A)
  \r           復帰            (0x0D)
  \b           後退空白        (0x08) (※ 文字集合内のみ)
  \f           改頁            (0x0C)
  \a           鐘              (0x07)
  \e           退避修飾        (0x1B)
  \nnn         八進数表現
  \xHH         十六進数表現
  \x{7HHHHHHH} 拡張十六進数表現
  \cx          制御文字表現
  \C-x         制御文字表現
  \M-x         超  (x|0x80)  
  \M-\C-x      超 + 制御文字表現


3. 文字種

  .        任意文字 (改行を除く)
  \w       単語構成文字 (英数字, "_" および 多バイト文字)
  \W       非単語構成文字
  \s       空白文字 (\t, \n, \v, \f, \r, \x20)
  \S       非空白文字
  \d       数字
  \D       非数字


4. 量指定子

  欲張り

    ?       一回または零回
    *       零回以上
    +       一回以上
    {n,m}   n回以上m回以下
    {n,}    n回以上
    {,n}    零回以上n回以下 ({0,n})
    {n}     n回

  無欲

    ??      一回または零回
    *?      零回以上
    +?      一回以上
    {n,m}?  n回以上m回以下
    {n,}?   n回以上
    {,n}?   零回以上n回以下 ({0,n}?)
    {n}?    n回

  強欲 (欲張りで、繰り返しに成功した後は回数を減らすような後退再試行をしない)

    ?+      一回または零回
    *+      零回以上
    ++      一回以上

    ({n,m}+, {n,}+, {n}+ は、ONIG_SYNTAX_JAVAでのみ強欲な指定子)

    例. /a*+/ === /(?>a*)/


5. 錨

  ^       行頭
  $       行末
  \b      単語境界
  \B      非単語境界
  \A      文字列先頭
  \Z      文字列末尾、または文字列末尾の改行の直前
  \z      文字列末尾
  \G      照合開始位置
          Ruby: 前回照合成功末尾位置
                (この仕様はRubyの実装に関するものであり、
                 正規表現ライブラリとは無関係)


6. 文字集合

  [^...]  否定集合 (最低優先度演算子)
  x-y     範囲     (xからyまで)
  [...]   集合     (文字集合内文字集合)
  ..&&..  積演算   (^の次に優先度が低い演算子)

     例. [a-w&&[^c-g]z] ==> ([a-w] and ([^c-g] or z)) ==> [abh-w]

  ※ '[', '-', ']'を、文字集合内で通常文字の意味で使用したい場合には、
     これらの文字を'\'で退避修飾しなければならない。


  POSIXブラケット ([:xxxxx:], 否定 [:^xxxxx:])

    alnum    英数字
    alpha    英字
    ascii    0 - 127
    blank    \t, \x20
    cntrl
    digit    0-9
    graph
    lower
    print
    punct
    space    \t, \n, \v, \f, \r, \x20
    upper
    xdigit   0-9, a-f, A-F


7. 拡張式集合

  (?#...)           注釈
  (?imx-imx)        孤立オプション
                      i: 大文字小文字照合
                      m: 複数行
                      x: 拡張形式
  (?imx-imx:式)     式オプション

  (式)              捕獲式集合
  (?:式)            非捕獲式集合

  (?=式)            先読み
  (?!式)            否定先読み
  (?<=式)           戻り読み
  (?<!式)           否定戻り読み

                    戻り読みの式は固定文字長でなければならない。
                    しかし、最上位の選択子だけは異なった文字長が許される。
                    例. (?<=a|bc) は許可. (?<=aaa(?:b|cd)) は不許可

                    否定戻り読みでは、捕獲式集合は許されないが、
                    非捕獲式集合は許される。

  (?>式)            原子的式集合
                    式全体を通過したとき、式の中での後退再試行を行なわない

  (?<name>式)       名前付き捕獲式集合
                    式集合に名前を割り当てる(定義する)。
                    (名前は単語構成文字でなければならない。最初の文字は
                     英大文字であってはならない。)

                    名前だけでなく、捕獲式集合と同様に番号も割り当てられる。
                    番号指定が禁止されていない状態 (10. 捕獲式集合 を参照)
                    のときは、名前を使わないで番号でも参照できる。

                    複数の式集合に同じ名前を与えることは許されている。
                    この場合には、この名前を使用した後方参照は可能であるが、
                    部分式呼出しはできない。


8. 後方参照

  \n          番号指定参照 (n >= 1)
  \k<name>    名前指定参照

  名前指定参照で、その名前が複数の式集合で多重定義されている場合には、
  番号の大きい式集合から優先的に参照される。
  (マッチしないときには番号の小さい式集合が参照される)

  ※ 番号指定参照は、名前付き捕獲式集合が使用され、
     かつ ONIG_OPTION_CAPTURE_GROUPが指定されていない場合には、
     禁止される。(10. 捕獲式集合 を参照)


9. 部分式呼出し ("田中哲スペシャル")

  \g<name>    名前指定呼出し
  \g<n>       番号指定呼出し (n >= 1)

  ※ 最左位置での再帰呼出しは禁止される。
     例. (?<name>a|\g<name>b)   => error
         (?<name>a|b\g<name>c)  => OK

  ※ 番号指定呼出しは、名前付き捕獲式集合が使用され、
     かつ ONIG_OPTION_CAPTURE_GROUPが指定されていない場合には、
     使用できない。 (10. 捕獲式集合 を参照)

  ※ 呼び出された式集合のオプション状態が呼出し側のオプション状態と異なっている
     とき、呼び出された側のオプション状態が有効である。

     例. (?-i:\g<name>)(?i:(?<name>a)){0} は "A" に照合成功する。


10. 捕獲式集合

  捕獲式集合(...)は、以下の条件に応じて振舞が変化する。
  (名前付き捕獲式集合は変化しない)

  case 1. /.../     (名前付き捕獲式集合は不使用、オプションなし)

     (...) は、捕獲式集合として扱われる。

  case 2. /.../g    (名前付き捕獲式集合は不使用、オプション 'g'を指定)

     (...) は、非捕獲式集合として扱われる。

  case 3. /..(?<name>..)../   (名前付き捕獲式集合は使用、オプションなし)

     (...) は、非捕獲式集合として扱われる。
     番号指定参照/呼び出しは不許可。

  case 4. /..(?<name>..)../G  (名前付き捕獲式集合は使用、オプション 'G'を指定)

     (...) は、捕獲式集合として扱われる。
     番号指定参照/呼び出しは許可。

  但し
    g: ONIG_OPTION_DONT_CAPTURE_GROUP
    G: ONIG_OPTION_CAPTURE_GROUP
    ('g'と'G'オプションは、ruby-dev MLで議論された。)

  これらの振舞の意味は、
  名前付き捕獲と名前無し捕獲を同時に使用する必然性のある場面は少ないであろう
  という理由から考えられたものである。
  これらのオプションについては、Rubyでは現在実装していない。


-----------------------------
補記 1. 文法依存オプション

   + ONIG_SYNTAX_RUBY
     (?m): 終止符記号(.)は改行と照合成功

   + ONIG_SYNTAX_PERL と ONIG_SYNTAX_JAVA
     (?s): 終止符記号(.)は改行と照合成功
     (?m): ^ は改行の直後に照合する、$ は改行の直前に照合する


補記 2. 独自拡張機能

   + 名前付き捕獲式集合   (?<name>...)
   + 名前指定参照         \k<name>
   + 部分式呼出し         \g<name>, \g<group-num>


補記 3. Perl 5.8.0と比較して存在しない機能

   + [:word:]
   + \N{name}
   + \l,\u,\L,\U, \X, \C
   + (?{code})
   + (??{code})
   + (?(condition)yes-pat|no-pat)

   * \Q...\E
     但しONIG_SYNTAX_PERLとONIG_SYNTAX_JAVAでは有効

   * \p{property}, \P{property}
     但しONIG_SYNTAX_PERLとONIG_SYNTAX_JAVAでは有効
     Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
     Print, Punct, Space, Upper, XDigit, ASCIIが指定できる。

     特性名の前に 'Is'前置詞を使用することは、ONIG_SYNTAX_PERLでのみ
     許されている。
     ex. \p{IsXDigit}.

     特性の否定演算子は、ONIG_SYNTAX_PERLでのみ許されている。
     \p{^...}, \P{^...}


補記 4. Rubyの日本語化 GNU regex(version 0.12)との違い

   + 戻り読み機能を追加
   + 強欲な繰り返し指定子を追加 (?+, *+, ++)
   + 文字集合の中の演算子を追加 ([...], &&)
     ('[' は、文字集合の中で通常の文字として使用するときには
      退避修飾しなければならない)
   + 名前付き捕獲式集合と、部分式呼出し機能追加
   + 多バイト文字コードが指定されているとき、
     文字集合の中で八進数または十六進数表現の連続は、多バイト符合で表現された
     一個の文字と解釈される
     (例. [\xa1\xa2], [\xa1\xa7-\xa4\xa1])
   + 孤立オプションの有効範囲は、その孤立オプションを含んでいる式集合の
     終わりまでである
     例. (?:(?i)a|b) は (?:(?i:a|b)) と解釈される、(?:(?i:a)|b)ではない
   + 孤立オプションはその前の式に対して透過的ではない
     例. /a(?i)*/ は文法エラーとなる
   + 不完全な繰り返し範囲指定子は通常の文字列として許可される
     例. /{/, /({)/, /a{2,3/
   + 否定的POSIXブラケット [:^xxxx:] を追加
   + POSIXブラケット [:ascii:] を追加
   + 先読みの繰り返しは不許可
     例. /(?=a)*/, /(?!b){5}/
   + 数値で指定された文字に対しても、大文字小文字照合オプションは有効
     例. /\x61/i =~ "A"
   + 繰り返し回数指定で、最低回数の省略(0回)ができる
     /a{,n}/ == /a{0,n}/
     最低回数と最大回数の同時省略は許されない。(/a{,}/)
   + 無限繰り返しの中で、長さ零での照合成功は繰り返しを中断させるが、
     このとき、中断すべきかどうかの判定として、捕獲式集合の捕獲状態の
     変化まで考慮している
     /(?:()|())*\1\2/ =~ ""
     /(?:\1a|())*/ =~ "a"



補記 5. 実装されているが、既定値では有効にしていない機能

   + 捕獲履歴参照

     (?@...) と (?@<name>...)

     例. /(?@a)*/.match("aaa") ==> [<0-1>, <1-2>, <2-3>]

     使用方法は、sample/listcap.cを参照

     有効にしていない理由は、どの程度役に立つかはっきりしないため。


補記 6. 問題点

   + UTF-8で、バイト値が適正な価かどうかのチェックは行なっていない。

     * 先頭バイトとして不正なバイトを一文字とみなす
       /./u =~ "\xa3"

     * 不完全なバイトシーケンスのチェックをしない
      /\w+/ =~ "a\xf3\x8ec"

     これを調べることは可能ではあるが、遅くなるので行なわない。


   + 文字種の判定は、多バイト文字の範囲では正しくない。

     多バイト文字は、実際の文字に関係なく単語構成文字(\w)と
     みなしている。(さらに、[:graph:], [:print:]にも含まれる)

     UTF-8の場合は、[U+0080 - U+00FF]の範囲だけ正しく文字種を
     判定するが、U+0100以降については単語構成文字とみなす。

終り
