想像してください。
あなたは、クライアントMさんの日記(テキストファイル)を元にして、
本を出版するという業務を担当しています。。
与えられた日記のテキストファイルを見ていると、
「4H22M15S」
という文字を見つけました。
文脈から判断するに、4時間22分15秒を表しているようです。
ここで上司から
「その表記は読者にとって見づらいから、○時間△分×秒って表示に置き換えてね。
あ、もちろんテキスト全体で同じような表現有れば全部ね。」
と言われました。
テキストファイルは数千行の内容で、一部に目を通すと
…
1月25日の勝田マラソンは4H25M56Sで完走することができた。
次のレースではサブ4を達成したい。久米島トライアスロンは5H21M20Sだ。
6月のバラモンキングは倍の距離なので気合を入れなければ。
補給食として仙豆を家庭菜園で育て、元帥に献上すればクビは免れるはずだ。
今日は重要な案件で秘密のファイルを作った。 パスワードは ”34HM300SABC”だ。
…
のように、日本語と「○H△M×S」形式の表現が入り混じっています。
さらに紛らわしいことに、パスワードの文字列も入っています。
素直に「H」を「時間」、「M」を「分」、という風に置換すると
パスワードがめちゃくちゃになってしまうので単純な置換ははできません。
(パスワードをテキストファイルに残すことなどの是非は置いておき)
「○H△M×S」形式だけを抽出し、「○時間△分×秒」に置き換えたい場合、
あなたならどうしますか?
例えば下記の様な選択肢が考えられますが、、
- 一つ一つ地道に検索していく(Ctrl+Fなどで検索できますよね)
- 可愛い部下を成長させるために、部下に丸投げする
- 上司にかみつく
- 途方に暮れる
- 正規表現を使う
今回は、5の「正規表現を使う」にチャレンジしましょう。
置換作業が一瞬で終わりますよ。
目次
正規表現とは
正規表現(regular expression)は、
複数の文字列を一つの形式でまとめて表現する方法です。
例えば、
- 火曜日
- 木曜日
- カレー曜日
- 土曜日
- 熊田曜子
の中から7曜だけを検索したいときは
「・曜日」という正規表現を用いて検索すると
- 火曜日
- 木曜日
- 土曜日
だけが検索結果にヒットします。
「・曜日」の・(ドット)がキーポイントで、
正規表現における・(ドット)は「任意の一文字」を表します。
この・(ドット)の様な特殊な意味を持つ文字のことを
「特殊文字」「メタ文字」などと呼びます。
「・」以外のメタ文字は
- ^(キャレット):行の先頭を表す
- $(ドル) :行末を表す
- +(プラス) :直前の文字の1回以上の繰り返し
- *(アスタリスク):直前の文字の0回以上の繰り返し
などなど。
地道に使いながら覚えるしか方法はないでしょう。
正規表現を使うには
正規表現に対応したテキストエディタを用いることで
検索や置換をスムーズに行うことができます。
残念ながらWindows標準搭載の「メモ帳」は正規表現に対応しておりません。
- 秀丸エディタ
- さくらエディタ
- Notepad++
- EmEditor
- Emacs
- Vi
などの、正規表現に対応したテキストエディタアプリをインストールする必要があります。
テキストエディタには有料のものもあるので注意してインストールしてください。
冒頭の問題の回答例
正規表現の詳しい説明は他のサイトに任せて、
冒頭の問題
「○H△M×S」形式から「○時間△分×秒」に置き換える
という操作を行ってみましょう。
※下記画像では秀丸エディタを用いています。
エディタによって正規表現検索・置換の方法は異なるため
詳しくはお使いのエディタのマニュアルを確認してください。
テキストファイルを開いたい状態で「置換」を操作。
置換ダイアログが出てくるので「正規表現」のボックスにチェックをいれます。
次に、検索のボックスに
(\d+)H(\d+)M(\d+)S
と入力し、置換のボックスに
\1時間\2分\3秒
と入力します
(エディタによっては$1時間$2分$3秒 と、\の代わりに$を使って入力します。)。
あとは「全置換」をクリック。
ちゃんと、狙い通り赤枠部分だけが「○H△M×S」形式から「○時間△分×秒」形式に置換され、
パスワードにはそのまま置換されずに済んでいます。
検索ボックス:(\d+)H(\d+)M(\d+)Sの説明
まず”(\d+)H”を分解すると
①()括弧(パーレン)
②\d
③ + (プラス記号)
④ H (ただの文字列)
に分けられます。
① は置換ボックスの箇所で説明します。
②は半角数字を表すメタ文字です。0-9の、任意の数字一文字を表します。
③は「直前の文字の1回以上の繰り返し」です。
④Hはそのまま普通の文字のHです。
つまり”\d+”という表現は「半角数字の1回以上の繰り返し」を意味します。
- 111111
- 123423849
- 2
- 343
などの文字列は全て正規表現の”\d+”で表されるということですね。。
置換ボックス:\1時間\2分\3秒の説明
\1 :検索にヒットした1番目の()で囲まれた要素
\2 :検索にヒットした2番目の()で囲まれた要素
\3 :検索にヒットした3番目の()で囲まれた要素
...
\の次にくる数字は、検索ボックスで使用した()の数だけ設定することができます。
秀丸エディタの場合は\1、\2、\3ですが
通常は$1、$2、$3と、$記号を用いることが多いです
(また、ここで使う$の意味は、冒頭で説明した「行末を表す$」とは異なるので注意してください)。
ポイントは、括弧で囲むと、その値を使って置換することができるということ。
例えば、置換対象の文字列が「4H25M56S」である場合、
「(\d+)H(\d+)M(\d+)S」で検索をかけると
\1には4、
\2には25、
\3には56
が格納されます。下図の様なイメージですね。
「\1時間\2分\3秒」の\1,\2、\3がそれぞれ、4、25、56と解釈されるため
置換の結果は「4時間25分56秒」となります。
別の例で、置換対象の文字列が「5H21M20S」である場合は
「(\d+)H(\d+)M(\d+)S」で検索をかけると
\1には5、
\2には21、
\3には20
が格納されます。
「\1時間\2分\3秒」の\1,\2、\3がそれぞれ、5、21、20と解釈されるため
置換の結果は「5時間21分20秒」となります。
置換時に値をそのまま使いたい場合は、括弧を突ければ
\1などの表現で値を引き継ぐことができるのです。
もう一つ例を挙げると
- ぼくはバナナがだいすきなの!
- ぼくは納豆がだいすきなの!
- ぼくはプロテインがだいすきなの!
と言う文を、もう少し大人っぽく
「私の好物は○○です」としたい場合、
ぼくは(.*)がだいすきなの!
を
私の好物は\1です
に置換すれば
\1の値が各行ごとにバナナ、納豆、プロテインに変換されるということです。
.*は任意の文字列を表します。
「ぼくは」を「私の好物は」に置換して、
「がだいすきなの!」を「です。」に置換して、
と2段階に分けて検索しても良いのですが、
正規表現を使って一度で済ませた方が、ちょっとスマートな気がします、、、よね?^^;;
ジョジョの奇妙な冒険こそ格好の練習の機会
もしジョジョの奇妙な冒険のセリフを正規表現で表せと言われれば
オラオラオラオラオラぁ! は
”[オラ]+ぁ!”
となり、
(※[]で囲むと、囲まれた部分を1ブロックとして扱います。
もし[]なしで”オラ+ぁ”としてしまうと、”オラララララララぁ”となってしまいます。)
無駄無駄無駄無駄無駄ぁ! や、
無駄無駄無駄無駄無駄無駄無駄無駄ぁ! は
”[無駄]+ぁ!”
という形で表せてしまうのです。ジョジョの紙面が大幅に節約できてしまいます。
あなたが冷静なうちは
”[無駄]+ぁ!”は「無駄無駄ぁ!」程度かもしれませんが
テンションが徐々にあがるにつれて
”[無駄]+ぁ!”が「無駄無駄無駄無駄無駄ぁ!」、
はたまた
「無駄無駄無駄無駄無駄無駄無駄無駄ぁ!」、
となっていくことでしょう。
ウリィ+!
まとめ
ところどころ脱線しましたが、言いたかったことは
「正規表現をマスターすればテキスト編集効率が格段に上昇しますよ」、
ということです。
今回は触れませんでしたが”\n”が改行を表したり、”\t”がタブを表したり、という
特殊な文字:エスケープシーケンス(エスケープ文字)と組み合わせることで
より一層効率UPします。
WEB上でも書籍でもいたるところに情報は転がっているので
興味を持たれた方はぜひ、「正規表現」「エスケープシーケンス」などで調べてみてください。
この文章を正規表現で一発置換するにはどうしたらいいか?なんて考えていると
ちょっとしたパズルを解いているみたいで楽しいですよ。
=====
編集後記:
2週間ほどプールに行けていないのですが、
どうも脳みその調子が悪いです。
プールでクロールをすると、肩甲骨と首回りの筋肉がほぐれて
血流が改善するのか?
頭も気分もスッキリする気がします(体は疲れますが)。
一日一新(一日にひとつ新しいことを行う):
・ストレングスファインダーの資料見直し&分析