パターンを使った置換

前回はVimの置換機能の基本を網羅的に紹介した。Vimでは単純に文字列を置換することもできるし、パターンを使ったより複雑な置換を行うこともできる。置換機能はデータの編集整理などにも便利で、専用のツールを使ったりプログラムを組んだりしなくとも、Vimだけでデータを編集することもできる。今回はそうした置換の使用例を紹介する。

パターンで使用できる内容は多岐に渡っている。置換や正規表現をよく使う方であれば結構な数を覚えておけるかもしれないが、ほとんどのユーザーは数個の指定を覚えるくらいが現実的なところではないだろうか。以降では、特によく使用する機能を取り上げておこう。

郵便番号データを加工していく

置換操作のサンプルとして、日本郵便が提供している郵便番号および住所等を記載したデータを使用する。「読み仮名データの促音・拗音を小書きで表記するもの - zip圧縮形式 日本郵便」から2020年3月31日付けの「全国一括(1,690,437Byte)」をダウンロードし、郵便番号と住所のみを取り出してタブ区切りにデータを変換しておく。次のようなデータだ。

置換操作で使用するデータ

データ件数は12万4,429件

このデータの件数は12万4,429件あり、手動で全てを編集するには現実的ではない量だ。このデータをHTMLデータに加工するケースを考える。具体的には、タブ区切りのデータを、次のようなフォーマットでHTMLデータの一部へ変換していく。

   <li>NNN-NNNN 住所</li>

まず、先頭の郵便番号を「NNN-NNNN」の形式に変換する。次のサンプルでは「:%s/^(…)/\1-/」として、「先頭の任意の3文字を”その3文字-“の形式に置換する」という命令を実行している。

郵便番号を「NNN-NNNN」の形式に変換する

実行結果

「:%s/^(…)/\1-/」はよく使われるパターンが入っており、覚えておきたい内容だ。まず、「^」が行頭を意味する。「^…」で行頭3文字分が対象となる。また、「^(…)」となっているので、対象となる先頭3文字は「\1」で後方参照できる。そして置換後文字列が「\1-」となっているから、先頭3文字に「-」を加えた文字列に置換されることになる。この指定は使えるようになっておきたい。

次に、郵便番号と都道府県の間のタブを全角スペースに変換している。これは単純に文字列の置換だ。gフラグを指定していないので、行ごとに最初のタブ1つだけが処理されることになる。

郵便番号と住所の間のタブを全角スペースに変換

実行結果

次に住所の間に入っているタブを削除する。残っているタブを削除するとこの条件を満たすので、次のようにタグを全て消すような置換を実行している。

タブを削除して住所をくっつける

実行結果

最後に、この文字列をli要素の中に入れるように置換を実行する。

データをli要素へ加工する

実行結果

最後の置換では行末を意味する「$」が使われている点と、後方参照が使われている点、さらにデリミタに「/」ではなく「@」を使っている点に注目しておきたい。「^(.*)$」という指定で行全体という意味になる。行全体を「\1」で後方参照できるようにしている。そしてli要素の中に「/」が入っているので、デリミタとして「/」ではなく「@」を使っているわけだ。置換対象や置換後文字列に「/」が含まれているときにはこの書き方がよく使われるので覚えておきたい。

置換は極めたい機能

慣れないと置換は難しいところもあるが、Vimの置換機能は強力で便利なので、ぜひとも習得していきたい。置換が使いこなせるようになってくると、これまで手動でやっていたようなデータの編集作業などを瞬時に終わらせることができるようになる。最初は苦労するかもしれないが、苦労しただけの見返りは得られるのではないだろうか。

付録: 置換関連機能テーブル

パターン 内容
^ 行頭(パターンの先頭でのみ指定可能)
$ 行末(パターンの末尾でのみ指定可能)
. 任意の1文字(行末には使用できない)
\%^ ファイルの先頭
\%$ ファイルの終了
\%V Visual領域の中
\%# カーソルの位置
\%’m マークm位置
\%数字l 指定行
\%数字c 指定列
\%数字v 指定仮想列
\_^ 行頭(パターンのどこでも指定可能)
\_$ 行末(パターンのどこでも指定可能)
\_. 任意の1文字(行末としても指定可能)
\< 単語の先頭
\> 単語の末尾
\zs 一致の開始を指定
\ze 一致の終了を指定
\^ ^
\$ $
. .
\e <ESC>
\t <TAB>
\r <CR>
\b <BS>
\n 行末
[] カッコ内に指定した文字のどれかに一致
\(\) グループ化
\1 1つ目の\(\)の中身に一致
\2 2つ目の\(\)の中身に一致
\3 3つ目の\(\)の中身に一致
\4 4つ目の\(\)の中身に一致
\5 5つ目の\(\)の中身に一致
\6 6つ目の\(\)の中身に一致
\7 7つ目の\(\)の中身に一致
\8 8つ目の\(\)の中身に一致
\9 9つ目の\(\)の中身に一致
\c 大文字小文字を区別せずに一致
\C 大文字小文字を区別して一致
\%d 10進数に一致
\%x 16進数に一致
\%o 8進数に一致
\%u マルチバイト文字に一致
\%U ラージマルチバイト文字に一致
\%C 合成文字に一致
\i 識別子文字
\I 識別子文字(数字は含まない)
\k キーワード文字
\K キーワード文字(数字は含まない)
\f ファイル名文字
\F ファイル名文字(数字は含まない)
\p 印刷可能文字
\P 印刷可能文字(数字は含まない)
\s 空白とタブ
\S 空白とタブ以外の文字
\d 数字([0-9])
\D 数字以外([^0-9])
\x 16進数([0-9A-Fa-f])
\X 16進数以外([^0-9A-Fa-f])
\o 8進数([0-7])
\O 8進数以外([^0-7])
\w 単語文字([0-9A-Za-z_])
\W 単語文字以外([^0-9A-Za-z_])
\h 単語の先頭文字([A-Za-z_])
\H 単語の先頭文字以外([^A-Za-z_])
\a アルファベット([A-Za-z])
\A アルファベット以外([^A-Za-z])
\l 小文字アルファベット([a-z])
\L 小文字アルファベット以外([^a-z])
\u 大文字アルファベット([A-Z])
\U 大文字アルファベット以外([^A-Z])
\_d 数字(行末を含む)
\_D 数字以外(行末を含む)
\_x 16進数(行末を含む)
\_X 16進数以外(行末を含む)
\_o 8進数(行末を含む)
\_O 8進数以外(行末を含む)
\_w 単語文字(行末を含む)
\_W 単語文字以外(行末を含む)
\_h 単語の先頭文字(行末を含む)
\_H 単語の先頭文字以外(行末を含む)
\_a アルファベット(行末を含む)
\_A アルファベット以外(行末を含む)
\_l 小文字アルファベット(行末を含む)
\_L 小文字アルファベット以外(行末を含む)
\_u 大文字アルファベット(行末を含む)
\_U 大文字アルファベット以外(行末を含む)
繰り返しパターン 内容
* 直前指定の0回以上の繰り返し(より長い方に一致)
\+ 直前指定の1回以上の繰り返し(より長い方に一致)
\= 直前指定の0回または1回の繰り返し(より長い方に一致)
\? 直前指定の0回または1回の繰り返し(より長い方に一致)
\{n,m} 直前指定のn回以上m回以下の繰り返し(より長い方に一致)
\{n} 直前指定のn回の繰り返し
\{n,} 直前指定のn回以上の繰り返し(より長い方に一致)
\{,m} 直前指定のm回以下の繰り返し(より長い方に一致)
\{} 直前指定の0回以下の繰り返し(より長い方に一致)
\{-n,m} 直前指定のn回以上m回以下の繰り返し(より短い方に一致)
\{-n} 直前指定のn回の繰り返し
\{-n,} 直前指定のn回以上の繰り返し(より短い方に一致)
\{-,m} 直前指定のm回以下の繰り返し(より短い方に一致)
\{-} 直前指定の0回以下の繰り返し(より短い方に一致)
置換後文字列で使える特別な文字列 内容
& 一致したパターン全体に一致
\& &
~ 前の置換文字列に一致
\~ ~
\0 一致したパターン全体に一致
\1 1つ目の\(\)の中身に一致
\2 2つ目の\(\)の中身に一致
\3 3つ目の\(\)の中身に一致
\4 4つ目の\(\)の中身に一致
\5 5つ目の\(\)の中身に一致
\6 6つ目の\(\)の中身に一致
\7 7つ目の\(\)の中身に一致
\8 8つ目の\(\)の中身に一致
\9 9つ目の\(\)の中身に一致
<CR> 行を2つに分割。<CR>はCtrl-V Enterで入力する
\r 行を2つに分割。<CR>はCtrl-V Enterで入力する
\<CR> キャリッジリターン(Ctrl-M)を挿入。<CR>はCtrl-V Enterで入力する
\n <NL>を挿入。改行はしない
\b <BS>を挿入
\t <Tab>を挿入
\ \
範囲指定 内容
開始行,終了行 開始行から終了行までを範囲とする
カーソルのある行のみを範囲とする
% ファイル全体を範囲とする
行指定 内容
数字 行番号
. カーソルがある行
$ ファイル末尾行
% 1,$に同じ
‘< ビジュアル選択の開始行
‘> ビジュアル選択の終了行
/パターン/ パターンに一致する行(後方一致)
?パターン? パターンに一致する行(前方一致)
+数字 一致した行からさらに指定行数分後方へ移動した行
-数字 一致した行からさらに指定行数分前方へ移動した行
フラグ 内容
c 置換ごとに確認。y (置換を実施)、l (置換の実施と置換の終了)、n (置換をスキップ)、ESC (置換を終了)、a (すべての置換を実施)、q (置換を終了)、Ctrl-E (スクリーンアップ)、Ctrl-Y (スクリーンダウン)
g 行に含まれるすべての一致対象を置換。このフラグを指定しなかった場合、行に含まれる最初に一致した対象のみが置換される
i パターンの大文字と小文字を区別しない
I パターンの大文字と小文字を区別する
n 置換を実行せずに一致する対象数を報告