読者です 読者をやめる 読者になる 読者になる

括弧に囲まれた英字を大文字に,半角スペースはアンダースコアに

tech vim

想像以上に手こずったのでメモ.

こんなデータがありまして.;

<First Line>
<Second Line>
<Third Line>
<Forth Line var1> / <Forth Line var2> / <Forth Line var3>
This is <Fifth Line>
Copyright COMPANY INC. <Sixth Line>

こんなデータに対し以下のような作業をしなければならない場面に出くわしました.

やることは,
括弧に囲まれた中の文字列,その内容は半角英数字限定,をすべて大文字にし,かつ半角スペースは _ アンダースコアにする.

こんな感じになれば良しと.;

<FIRST_LINE>
<SECOND_LINE>
<THIRD_LINE>
<FORTH_LINE_VAR1> / <FORTH_LINE_VAR2> / <FORTH_LINE_VAR3>
This is <FIFTH_LINE>
Copyright COMPANY INC. <SIXTH_LINE>

結果やったこととは,手続きを 2 つに分け,このような感じに.

まず括弧内の半角英字を全て大文字にし.;

:%s/<.\{-}>/\U&/g

でもって,括弧内にある半角スペースにアンダースコア "_" を埋める.

:%s/<\(\u\+\s\)\+.\{-}>/\=substitute(submatch(0)," ","_","g")/g

一応それなりにイメージ通りの結果になってくれたのですが,絶対もっとスマートな方法があるはず,とは思っています.
今の自分はこれが精一杯の様子.

もしこれを見て,「いやいやそんな面倒なことやらなくても,ホラ...」的なことございましたら,是非々々ご教示をば.

VimVim / mistagrrr



背景

実は Excel 上での作業.
式でサクッとできると思ってはいたのですが,ちょっとした所が行き届かなく,その部分をいちいち手でやるのが嫌だな,と.かとて VBA 組めば出来るのでしょうが,ただでさえ VBA と言うだけでモチベーションだだ下がりなのに*1,費用対効果的にもあまり報われないものであることもあり,じゃ頭の体操程度に,と vim 上にステージを移しチャレンジしてみることにしたのです.

1 ステップ目の,"括弧内の文字列を全て大文字に",と言うのはすんなり解決.
問題は 2 番目の "括弧内にある半角スペースをアンダースコアに" が思った以上にハマった,と.

以下,今回の作業の中で参考にさせていただいた情報を挙げ,必要に応じ個人的なメモを加えておきたいと思います.

括弧内の半角英字を大文字にする

カーソルや選択範囲のもとの文字を大文字/小文字にする手続きはたくさんあるのですが,文書全体を一括で変換するという情報は思いのほか少なくて...

一番最初にピンと来たのはこちら.;

ある範囲を一括で大文字→小文字変換するには以下のようにする。
:'a,.s/[A-Z]/¥L&/g

置き換え文字列 \L& なのでしょうが,まず \L って何? って.;

正規表現で置換する際、結果の大文字/小文字を指定することができます。 置換後のパターンに ¥u があると、次の文字は大文字になります。¥l があると小文字になります。

:s/\w+/\u\0/g
"bram moolenaar" → "Bram Moolenaar"

気になって :h \L で見てみると良く分からなかったのですが,別件でたまたま目にしたこちらでそう言うことかと.;

例:
:s/a|b/xxx\0xxx/g "a b" を "xxxaxxx xxxbxxx" に置換
:s/([abc])([efg])/\2\1/g "af fa bg" を "fa fa gb" に置換
:s/abcde/abcMde/ "abcde" を "abc", "de" (2行) に置換
:s/$/^VM/ "abcde" を "abcdeM" に置換
:s/\w+/\u\0/g "bla bla" を "Bla Bla" に置換
:s/\w+/\L\u/g "BLA bla" を "Bla Bla" に置換

Note: "\L\u" を使うと単語の最初の文字をキャピタライズできる。これは Vi や古い Vim とは互換性がない。それらの古い環境では "\u" は "\L" をキャンセルする。
"\U\l" も同様。

via. :h :s%

つか,:h :s% に書かれているって想像つく?

ちなみに \L&&
これは,こういうことらしいです,;

文字数カウントできないのは不便だなーとか思ったので投下。
viで文字数カウント
:%s/./&/g

置換先の & は、《マッチしたパターン全体に置き換わる》ものなのだそう*2。つまり同じ答えが入ってくる、というイメージ。
先の :s/\w\+/\u\0/g\0 はこの & に同義っぽい。

括弧内にある半角スペースをアンサースコアに

諦めかけた時にこれを目にして「あぁ〜」と.

置換文字列が "\=" で始まるとき、それ以降の文字列は式として解釈される。

とこんなところ.
はい,おしまい.

*1:vba は,いやそもそも ms 製品がほんっとーに嫌いだったりしますw

*2:':h s/&' で飛ぶ先は,'s/\' なんだけど...?