■置換文字列内のメタ文字

 置換文字列内で使用できるメタ文字には、次の3字があります。
   \  エスケープ文字の開始
   @  正規表現検索で一致した部分の参照
   |  正規表現検索での並列置換の区切り

 このメタ文字を使って、次のような高度な置換を行ないます。


■特殊な文字コードへの置換

 置換文字列内には、通常、改行やタブの制御コード等は、含められませんが、 「エスケープ文字」を使うと、置換文字列内で、各種の特殊な文字コードを表記できます。 置換文字列が実際に置換で使われる時、その中のエスケープ文字は、それが 表わす文字コードに変換されます。

 エスケープ文字の表記は、メタ文字 \ と、それに続くアルファベット1字か、 場合によっては、それに16進または10進の数字列が続きます。 次に、置換文字列内で表記可能なエスケープ文字の一覧を示します。


 \t   水平タブコード( \x09 )
 \n   改行コード( CR/LF, LF, CR のどれか、現改行種別に依存 )
 \r   キャリッジリターンコード( \x0D )
 \v   垂直タブコード( \x0B )
 \f   フォームフィードコード( \x0C )
 \e   エスケープコード( \x1B )
 \xnn   16進2桁 nn の1バイトコード
 \Xnnnn  16進4桁 nnnn の2バイトコード
 \Jnnnn  10進4桁 nnnn の句点コード

 メタ文字 \ の次が上記の文字以外の場合、その文字自身を表わします。 これは、メタ文字を、通常の文字として表わす時などに使えます。 例えば、\\ は \ 自身を表わします。 また、\@ は @ 自身を、\| は | 自身を表わします。

 \x と \X の1バイトと2バイトの文字コードは、現状、Shift-JIS コードに限定されます。 また、\J の句点コードは、第1面内に限定されます。次に、これらの例を示します。

  A   \x41
  ア   \xB1
  あ  \X82A0 または \J0402
  亜  \x889F または \J1601

 エスケープ文字を使った置換の例を、次に示します。

(例1) ABC を XYZ とタブコードに置換する場合

 検索文字列: ABC
 置換文字列: XYZ\t
なお、この場合、検索文字列に、必ずしも正規表現を使わなくても構いません。


(例2)3個以上連続する改行コードを1個の改行コードに置換する場合

 検索文字列: \n\n\n+
 置換文字列: \n
なお、この場合、検索文字列に、必ず正規表現を使う必要があります。


■一致部分を参照する置換

 置換文字列内で、メタ文字 @ に 1〜9 の数字1字が続く表記
   @1 @2 @3 ... @9
は、それぞれ、検索文字列内の正規表現の第1〜9番目の「参照グループ」に一致した文字列部分への参照を表わします。 従って、この表記が表わす置換文字列の部分は、固定的なものではなく、 実際に置換が行なわれる時点で、検索で一致していた文字列部分に動的に置き換えられます。
 なお、この表記は、\0 \1 \2 ... \9 の表記にすることもできます。 いずれにしても、置換文字列内で、この表記を使う場合、検索文字列は、必ず、 正規表現にする必要があります。

 これを使うと、例えば、二重引用符で囲まれた文字列を検索して、それから 二重引用符の囲いを除去して、その中身だけの文字列に置換することができます。 この場合、
   検索文字列: "@([^"]*)"
   置換文字列: @1
となります。

 また、例えば、「A→B」という文字列部を、「B←A」に置換する場合は、
   検索文字列: 「@([^「→」]*)→@([^「→」]*)」
   置換文字列: 「@2←@1」
となります。なお、ここで、A と B は、「 と → と 」 の3字を使っていない任意の文字列が対象になります。

 メタ文字 @ に続く数字1字に対応する「参照グループ」が検索文字列内にないか、または、 その「参照グループ」に一致する部分がない場合、その表記は、実際の置換時に、 空文字列に変換されます。

 置換文字列内では、@0( または \0 )の表記も使えます。これは、 検索文字列の正規表現全体に一致した文字列部分への参照を表わします。

 例えば、各論理行の先頭に「> 」を付けたい場合は、
   検索文字列: ^.*$
   置換文字列: > @0
として、置換を実行すればできます。ちなみに、この操作は、「慣用語句入力」を使えば、もっと簡単にできます。例えば、 「> 」をクリップボードに入れておいて、対象行を行範囲選択して、「各選択範囲の先頭に貼付け」を行ないます。あるいは、 同様に行範囲選択してから、「メール」集の「各選択範囲を引用部化」を実行します。


■並列置換

 並列置換では、複数の検索文字列パターンと、それぞれに対応する複数の置換文字列が あります。その複数の検索文字列パターンは同時に検索されて、そのうちの1つが 見つかると、それに対応する置換文字列に置換されます。

 並列置換を行なう場合、検索文字列は、必ず、正規表現にする必要があります。また、 置換文字列のメタ文字が有効なっている必要があります。

 並列置換の検索文字列と置換文字列内の各並列要素は、メタ文字 | で区切ります。 例えば、
   検索文字列: A|B|C
   置換文字列: X|Y|Z
とすると、これは、A または B または C を検索して、A が見つかればそれを X に置換し、 B が見つかればそれを Y に置換し、C が見つかればそれを Z に置換します。

 ちなみに、もし並列置換の機能がなければ、この例のような置換を行なう場合、 A→X, B→Y, C→Z の3回の置換を行なう必要があります。

 並列置換の有用性は、これだけではなく、もっと本質的なところにあります。例えば、
   A→B, B→C, C→A
の置換を、
   ---A---B---C---
のテキストに対して行なう場合、並列置換だと一気に、
   ---B---C---A---
となりますが、3回の置換だと、1回目の置換で、
   ---B---B---C---
となってしまいます。これに2回目の置換を行なっても、意味がありません。

 検索文字列内の並列要素を、空文字列に置換するには、それに対応する 置換文字列内の並列要素を空文字列にします。例えば、
  検索文字列: A|B|C
  置換文字列: X||Z
では、A→X, B →空文字列, C→Z、に置換されます。また、
  検索文字列: A|B|C
  置換文字列: X|Y|
では、A→X, B →Y, C→空文字列、に置換されます。また、
  検索文字列: A|B|C
  置換文字列: X||
では、A→X, B →空文字列, C→空文字列、に置換されます。

 検索文字列が並列要素に区切られるのは、その正規表現の最上位の「分岐」に対してだけです。例えば、
  検索文字列: A|(B|C)|D
  置換文字列: X|Y|Z
では、A が X に置換され, (B|C) に一致する部分が Y に置換され、
D が Z に置換されます。また、
  検索文字列: (A|B)|(C|D)
  置換文字列: X|Y
では、(A|B) に一致する部分が X に置換され、(C|D) に一致する部分が Y に
置換されます。また、
  検索文字列: (A|B|C)
  置換文字列: X|Y
では、検索文字列に最上位の分岐がないので、(A|B|C) に一致する部分が X に 置換されますが、Y に対応する検索文字列内の並列要素はありません。

 置換文字列内にメタ文字 | がない場合、並列置換は行なわれません。例えば、
  検索文字列: A|B|C
  置換文字列: X
では、並列置換は行なわれません。この場合は、通常の置換で、A|B|C に一致する 部分が、X に置換されます。

 最後に、並列置換に、前述の「一致部分を参照する置換」を使った例を示します。まず、注意すべき例を挙げます。
  検索文字列: @(apple)|@(orange)
  置換文字列: @2|@1
これは、一見、apple を orange に、orange を apple に置換するようですが、 @(apple) に一致した時は、@(orange) には一致していないので、@2 は、空文字列に なります。そのため、apple は空文字列と置換されてしまいます。また、orange に 一致する場合も同様です。

 次の例は、C言語の行コメントとブロックコメントの部分を、非コメント化する (コメントの中身だけを残す)置換です。
  検索文字列: #m//@(.*)$|/\*@((.|\n)*)\*/
  置換文字列: @1|@2
ここでは、#m で最小一致優先にしていますが、そうしないと、複数のブロックコメントが ある場合に、各終端の */ をうまく捕捉できないからです。