2010年8月18日水曜日

gensub = n番目に見つかった文字列を置き換える(Gawk専用) - AWK

AWKの文字列操作関数と関連機能
○Gawk on Windows ○Gawk ×mawk32 ×Mawk ×awk
文字列を置き換えます。n番目に見つかった文字列を置き換える、といった事も出来ます。

o gsubsubとは違って、対象文字列を上書きしない特徴があります。


**** 書式
--------
gensub( 置換する条件, 置換後の文字列, 置換方法 [, 対象文字列] )
--------

o この関数は、Gawkの拡張機能です。
o 置換する条件 -- 正規表現で指定します。左右に/を付けます。例: /ミク/
o 置換後の文字列 -- こちらは、普通の文字列を指定します。例: "Miku"
   + 「\」を使う特殊な指定があります。詳しくは、この説明の少し下
o 置換方法 -- 数字、もしくは「g」や「G」を指定します。
   + 数字を指定した時、n番目に見つかった文字列だけを置き換えます。
   + 「g」や「G」を指定した時、見つかった文字列を全部置き換えます。
o 対象文字列 -- 文字列や数値です。省略すると、変数 $0を使います。
   + この関数は、対象文字列を上書きしません。(= gsubsub とは異なります)
o 戻り値 -- 置換結果の文字列

** 数値の使用について
o 文字列を指定する所は、数値も指定出来ます。
   + 6桁を超える数値を指定する時は、数値から文字列に自動変換する時の最大桁数を増やします。
   + (変数CONVFMTを使用)

** 「置換後の文字列」の特殊な指定について
o 置換する条件の一部を丸括弧で括ると、「\\」+番号で使用出来ます。
   + (\\0はいつでも使用できます。)
--------
v = gensub(/(ルカ)(.+)(ミク)(.+)/, "\\3\\4\\1\\2", "g", "ルカ様ミクさん");
print v; # 結果は、ミクさんルカ様
--------

   + \\0 = 置換する条件に一致した文字列
   + \\1 = 置換する条件に一致した文字列の内、最初の丸括弧で括った部分
   + \\2 = 置換する条件に一致した文字列の内、2番目の丸括弧で括った部分
   + \\9 = 置換する条件に一致した文字列の内、9番目の丸括弧で括った部分
   + (10番目以降は非サポートです。)


**** 使用例
--------
BEGIN {
  print gensub(/ミク/, "Miku", 2, "ミクさん、ミクさん。"); # ミクさん、Mikuさん
  print gensub(/ミク/, "Miku", "g", "ミクさん、ミクさん。"); # Mikuさん、Mikuさん
  print gensub(/ミク/, "Miku", "GMiku", "ミクさん、ミクさん。"); # g と同じです。
  print gensub(/39/, "ミク", 2, 39.39); # 39.ミク
}
{
  print gensub(/ミク/, "Miku", "g"); # 対象文字列の指定が無い時は、$0を置換します。
  print gensub(/(ミク)さん/, "\\0\\1みく", "g"); # ミクさんミクみく
}
--------

o 行末のセミコロンは、C言語の書き方に合わせました。無くても動きます。


**** 機能
o 指定した条件で、文字列や数値を置き換えます。
o gsubsubと異なり、対象文字列を直接変更する事はしません。
o 対象文字列を省略すると、変数 $0を使います。
o 見つかった所を置き換えて、置き換えた結果を返します。

o 文字列の代わりに数値を指定すると、数値を文字列に変換してから使用します。
   + 長い整数を指定すると、最後の方の桁が0になったり、浮動小数点形式になります。
   + 実数を指定すると、6桁までに丸めたり、浮動小数点形式になります。
   + この動作は変える事も出来ます。詳しくは、「数値から文字列にする時に、実数を7桁以上表示させる方法

o この他、置換方法に「1以上の整数、g、G」以外の文字(例えばM)を指定すると、最初に見つかった文字列だけを置換します。
o この機能をサポートしていない処理系があります。


** 処理系に依存する動作
o この機能をサポートしている処理系は、次の通りです。
   + Gawk on Windows 3.1.7
   + Gawk for Windows 3.1.6


**** メモ
o \\10を指定した時、Gawkは \\1 + "0" と解釈して実行します。

o AWKプログラム
--------
BEGIN {
  print gensub(/(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)/, "\\10", "g", "z1234567890z");
  print gensub(/(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)/, "\\10", "g", "z12345678910z");
  print gensub(/(1)(2)(3)(4)(5)(6)(7)(8)(9)(210)/, "\\10", "g", "z123456789210z");
  print gensub(/(A)(B)(C)(D)(E)(F)(G)(H)(I)(a)/, "\\10", "g", "zABCDEFGHIaz");
}
--------

o 実行結果
--------
z10z
z10z
z10z
zA0z
--------



**** 確認した処理系
o Gawk on Windows 3.1.7
o Gawk for Windows 3.1.6
o mawk MBCS (32bit版) 1.3.3 -- 非対応
o Mawk for Windows 1.3.3 -- 非対応
o original = the one true awk(updated May 1, 2007) -- 非対応


==
関連ページ:
    ▼AWKの文字列操作関数と関連機能▼ABC順
    ▼AWKプログラムを書く▼ABC順
    ▼AWK
    ▼制作メモ
    > toupper = アルファベットを大文字にする
    tolower = アルファベットを小文字にする
    $0 = 最後に入力したデータ、1行分
    +
    gsub = 文字列を置き換える
    sub = 文字列を、最初の1つだけ置き換える
    CONVFMT = 数値を文字列に自動変換する時の書式
    IGNORECASE = 文字列比較の時に、大文字小文字を区別させない(Gawk専用)
(2010年9月28日訂正。\\数字で使用出来るのは\\9まで)