スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Prev.    Category    Next 

Step by step 正規表現入門 - 正規表現を使ったエディターでの置換

正規表現の最小限の知識が身に付いたところで、ルールの説明を一旦とめて、 正規表現を使ったエディターでの置換の方法について説明しましょう。

実際のコーディングで使うような例で説明した方が良さが伝わりやすいと思って、 C++ のサンプルを考えてみました。

置換のサンプル

まず、次のような列挙型の定義があったとします。
enum FooType {
    FooA,
    FooB,
    FooC
};
こういった列挙型を使った switch 文を書くことはよくあります。例として列挙型を文字列でダンプ表示するための関数を作ります。 これを作るとき、列挙型定義をコピペして、正規表現で置換するとすぐに作れるようになります。

  1. まず、ダンプ用関数の雛形を用意します。
    std::ostream &operator<<(std::ostream &out, FooType val)
    {
        switch (val) {
          default:
            out << (static_cast<int>(val)) << " (Not FooType)";
        }
        return out;
    }
    
  2. 列挙型定義の部分を貼り付けます。
    std::ostream &operator<<(std::ostream &out, FooType val)
    {
        switch (val) {
        FooA,
        FooB,
        FooC
          default:
            out << (static_cast<int>(val)) << " (Not FooType)";
        }
        return out;
    }
    
  3. 貼り付けた部分を置換します。
  4. 以下のような定義になって完成です。
    std::ostream &operator<<(std::ostream &out, FooType val)
    {
        switch (val) {
          case FooA: out << "FooA"; break;
          case FooB: out << "FooB"; break;
          case FooC: out << "FooC"; break;
          default:
            out << (static_cast<int>(val)) << " (Not FooType)";
        }
        return out;
    }
    
置換に使う正規表現のパターンと置換後の文字列は以下のようになります。
正規表現 ([a-zA-Z_0-9]+),?
置換後文字列   case \1: out << "\1"; break;
FooA などのマッチ時の文字列を指定するために () のグルーピングを使っています。
ここでのグルーピングは前回の複数指定とは関係なく、取り出す文字列の指定のためだけのものです。

この () によるマッチ文字の取得はプログラミング時にもよく使われます。
() はパターンの複数指定よりもむしろマッチ文字の取得としての用途の方が重要だと思います。

置換後の文字列でマッチした文字列を取り出すには以下のメタ文字を使います。
\番号
番号は () の出てきた順で、 \1, \2, ... といった感じで記述します。 この例では 1 個しか出てきていないので、 \1 です。
\0 とした場合はパターン全体でマッチした部分(FooA, など)となります。

エディターの置換機能の使い方

実際の置換を各エディターでやって行きましょう。

Emacs

Emacs では M-% で逐次置換(query-replace)になります。 正規表現による置換のコマンドは C-M-% (ESC Ctrl+Shift+5) または M-x query-replace-regrep で実行します。

コマンドを実行すると正規表現、置換後文字列を聞かれるので、それぞれ入力します。
このとき、前回説明したように Emacs では () の前に \ を付ける必要がある点に注意してください。
Query replace regrep: \([a-zA-Z_0-9]+\),?
with:   case \1: out << "\1"; break;


入力後は通常の逐次置換と同様の操作で置換していくことができます。
よく使うキーは次のものです。詳しくは ? でヘルプを見てください。
キー 機能
y または スペース 置換実行(1 つ)
n スキップ
! 残りすべての置換を実行
^ 前のマッチ位置に戻る
q または Return 中止

英語キーボードならいいのでしょうが、 C-M-% はかなり押しづらいです。 以下のような感じで割り当てを .emacs.el に書いておくといいでしょう。
(global-set-key "\M-5" 'query-replace-regexp)

Visual Studio

[編集] → [検索と置換] → [クイック置換] (Ctrl+H)などで置換ダイアログを呼び出します。
検索のときと同様にオプションで正規表現にチェックを入れておきます。

Visual Stodio の場合は置換用のグルーピングは () ではなく、 {} を使います。
また、 ? は使えないので、 * で代用します。

grep_vs_rep.png

K2Editor

[検索] → [置換] (Ctrl-R) などで置換ダイアログを呼び出します。
検索のときと同様に正規表現にチェックを入れておきます。
grep_k2_rep.png

連続して置換していくので、 [連続置換] の方のボタンをクリックして、置換していきます。

秀丸エディター

[検索] → [置換] (Ctrl-R) などで置換ダイアログを呼び出します。
検索のときと同様に正規表現にチェックを入れておきます。
grep_km_rep.png
連続してするには、 [置換の前に確認] にチェックを入れて、 [全置換] をクリックします。

なお、秀丸はカーソル位置からの置換はできないので、サンプルはもっと絞ったパターンにしています。

欲張りマッチとものぐさマッチ

以下のような文章で強調文字を取得するパターン <em>(.*)</em> を使ったとします。
<em>正規表現</em>は<em>便利</em>です
この時マッチするのは "正規表現</em>は<em>便利" の文字です。
正規表現ではこのようになるべく長い文字列がマッチすることを欲張りマッチまたは最大マッチといい、 なるべく短くマッチすることをものぐさマッチまたは最小マッチといいます。

正規表現では通常は欲張りマッチとなっています。
欲張りマッチで余分なマッチをしてしまうことはよくありますが、 たいていパターンを工夫すれば解決できるので、入門としてはこれ以上詳しくは説明しません。

ただ、エディターによってはオプションで簡単に切り替えられるので、 用語としては覚えておくといいでしょう。

次は ?

置換を覚えて頻繁に書いていると空白を指定する [ \t] や変数用の [a-zA-Z0-9_] などを結構使います。 これを何度も書いていると結構めんどくさくなると思います。
次はこれを楽に書く方法を紹介しましょう。
関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
11位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
2位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

07月 | 2017年08月 | 09月
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。