Perl風検索/置換とは?

※ある程度勉強しないと使えません。

 Perlに近い正規表現で検索や置換を行います。不要な人が間違えて使わないように、UIではわざと「正規」と呼ぶのは避け、このヘルプ内でのみ正規表現と書いています。実装は鬼車(http://www.geocities.jp/kosako3/oniguruma/)をUTF-16LEで動かしています。改行コードの種類によらず、内部データは\nを改行としています。その他、バグらしき動作があった場合、それはおそらく真魚のバグ、もしくは鬼車の仕様です。断じて鬼車のバグであるという自信がある場合以外は、オリジナルの配布元に質問しても解決にはならないでしょうから、迷惑をかけないでください。

以下は鬼車のドキュメントです。

鬼車 正規表現 Version 3.6.0    2005/02/01

使用文法: 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      超 + 制御文字表現 コードポイント値

  ※ \bは、文字集合内でのみ有効


3. 文字種

  .        任意文字 (改行を除く)

  \w       単語構成文字

           Unicode以外の場合:
             英数字, "_" および 多バイト文字。

           Unicodeの場合:
             General_Category -- (Letter|Mark|Number|Connector_Punctuation)

  \W       非単語構成文字

  \s       空白文字

           Unicode以外の場合:
             \t, \n, \v, \f, \r, \x20

           Unicodeの場合:
             0009, 000A, 000B, 000C, 000D, 0085(NEL), 
             General_Category -- Line_Separator
                              -- Paragraph_Separator
                              -- Space_Separator

  \S       非空白文字

  \d       10進数字

           Unicodeの場合: General_Category -- Decimal_Number

  \D       非10進数字

  \h       16進数字    [0-9a-fA-F]

  \H       非16進数字



4. 量指定子

  欲張り

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

  無欲

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

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

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

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

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


5. 錨

  ^       行頭
  $       行末
  \b      単語境界
  \B      非単語境界
  \A      文字列先頭
  \Z      文字列末尾、または文字列末尾の改行の直前
  \z      文字列末尾
  \G      照合開始位置(*)

          * Ruby Regexp:
                 前回照合成功末尾位置
                (この仕様はRubyの実装に関するものであり、
                 正規表現ライブラリとは無関係)


6. 文字集合

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

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

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


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

    Unicode以外の場合:

    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

    Unicodeの場合:

    alnum    Letter | Mark | Decimal_Number
    alpha    Letter | Mark
    ascii    0000 - 007F
    blank    Space_Separator | 0009
    cntrl    Control | Format | Unassigned | Private_Use | Surrogate
    digit    Decimal_Number
    graph    [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
    lower    Lowercase_Letter
    print    [[:graph:]] | [[:space:]]
    punct    Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
             Final_Punctuation | Initial_Punctuation | Other_Punctuation |
             Open_Punctuation
    space    Space_Separator | Line_Separator | Paragraph_Separator |
             0009 | 000A | 000B | 000C | 000D | 0085
    upper    Uppercase_Letter
    xdigit   0030 - 0039 | 0041 - 0046 | 0061 - 0066
             (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. 独自拡張機能

   + 16進数数字、非16進数字  \h, \H
   + 名前付き捕獲式集合      (?<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)との違い

   + 16進数字タイプ追加 (\h, \H)
   + 戻り読み機能を追加
   + 強欲な繰り返し指定子を追加 (?+, *+, ++)
   + 文字集合の中の演算子を追加 ([...], &&)
     ('[' は、文字集合の中で通常の文字として使用するときには
      退避修飾しなければならない)
   + 名前付き捕獲式集合と、部分式呼出し機能追加
   + 多バイト文字コードが指定されているとき、
     文字集合の中で八進数または十六進数表現の連続は、多バイト符合で表現された
     一個の文字と解釈される
     (例. [\xa1\xa2], [\xa1\xa7-\xa4\xa1])
   + 文字集合の中で、一バイト文字と多バイト文字の範囲指定は許される。
     ex. /[a-あ]/
   + 孤立オプションの有効範囲は、その孤立オプションを含んでいる式集合の
     終わりまでである
     例. (?:(?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{,}/)
   + /a{n}?/は無欲な演算子ではない。
     /a{n}?/ == /(?:a{n})?/
   + 無限繰り返しの中で、長さ零での照合成功は繰り返しを中断させるが、
     このとき、中断すべきかどうかの判定として、捕獲式集合の捕獲状態の
     変化まで考慮している
     /(?:()|())*\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"

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

終り

置換について

 置換は鬼車によらず、真魚側で実装しています。後方参照(前方参照?)が使えます。$1$9でカッコを指定するのが基本ですが、\1\9も同様に動作します。$0でマッチした部分全体を指定できます。\n\tはそれぞれ改行とタブ文字を指定します。