Step by step 正規表現入門
はじめに
最近ではスクリプト系の言語はもちろん C++ 以降の言語ではほとんど正規表現が標準機能として使えるようになっています。 C++ でも C11 の新規約では正規表現が標準ライブラリとなりました。今後、正規表現はプログラミングで当たり前のように使われる流れにあると言えるでしょう。
何故正規表現がそんなに使われるのでしょうか?
それは正規表現を使えば、圧倒的に文字列処理が簡単にかけるからです。
また、プログラミング言語で使えるだけでなく、 高機能なエディターでは正規表現による検索と置換が行えます。 これはコードリーディングやコーディングを楽にしてくれます。
プログラミングをするのならば、正規表現を知らないのはもったいないです。
ただ、正規表現を覚えようとした場合、 ルールもたくさんありますし、 言語やエディターの説明では基本的なものからめったに使わないものまで まとめて説明されがちです。 そこで、 Step by Step で少しずつ覚えていけるような正規表現の入門を書いてみました。
また、実際に使いながらの方が覚えやすいので、 以下の主要なエディターでの使い方も説明しています。
- Emacs
- Visual Studio
- K2Editor
- 秀丸エディター
対象読者
プログラマー向けの内容になっています。ただ、プログラミングの知識がないと理解できない ということはないんじゃないかなと思います。
進め方
進め方は基本的に最初から順番に始めてください。ただし、途中でやめても、そこそこ役に立つ構成にしています。 途中でやめたとしても、それまでの知識で使っていれば、 次の情報も知りたいとなるかもしれません。 その時また続きを読んでください。
さっと知りたいという場合はまとめページを見てください。 細かい説明を省いて、必要な情報を簡単にまとめています。
また、正規表現はだいたい知っているから、エディターでの使い方を知りたいという人は以下のページを見てください。
Step by step 正規表現入門 - 英数字とエディターでの検索
そのための正規表現の最初のステップです。
英数字, _(アンダーバー)はそのまま
英数字とはアルファベット(a-z A-Z)、数字(0-9)です。また、プログラミングの変数名などには _(アンダーバー) も使います。これらは単語用文字と呼ばれ、正規表現ではそのまま使えます。難しく考えることはなく、英数字 _ では正規表現による検索も文字列の検索と一緒ということです。
日本語対応しているものであれば、漢字のような全角文字も使えます。これらも英数字同様そのままの文字となります。
エディターの検索機能の使い方
いくつかのエディターで正規表現を使った検索の仕方を紹介します。ここでご紹介したいのは通常のファイル内の検索ではなく、 フォルダー(プロジェクト)内の複数のファイルにまたがった検索です。 これは grep 検索と呼ばれることがあります。
こちらを中心に説明しています。
この grep 検索は正規表現を使わなかったとしても便利な機能なので、 これだけ覚えておいても損はないと思います。
ここにあげたエディターでなくても、高機能なエディターであれば、 正規表現による検索や置換の機能はまず付いていると思います。 ここでの記事を参考に自分の愛用のエディターで検索を試しながらやってみてください。
grep
と、いきなりエディターの説明ではないのですが、 grep は名前の由来となっているコマンドラインプログラムです。これはこれで便利ですし、 Unix 系であればまずインストールされているので、 こちらの紹介もしておきます。
Windows 版もいろいろ公開されているので、インストールすれば使えます。
- Grep for Windows
- 【レビュー】Cygwinより手軽にUNIX風環境が手に入る「Gow」 (1) UNIX風環境をWindows OS上で使用してきた時代 | パソコン | マイナビニュース
使い方は次のようになります。
grep [-i] 正規表現 ファイル [... ](例)
$ grep include *.h *.cppファイルは複数指定が可能で通常 *.cpp のようなフィルターを使います。 後、オプションとして大文字小文字を区別しない -i をよく使います。
プログラムを実行すると検索結果の一覧が表示されます。
Emacs
Emacs では前節の grep を利用します。 M-x grep や eshell 上で grep コマンドを実行します。実行すると検索結果が別バッファでリストに表示されます。
ただ grep を実行するのと違い、このリストでマウスの中ボタンクリックや Enter キーを押すと結果位置にジャンプすることができます。

さらに私の作った lisp も使えば、検索位置へのジャンプはより便利になります。
後で説明する K2Editor や秀丸エディターではファイルをまたがった検索は grep という名前になっているだけですが、 Emacs では実際に grep プログラムを呼び出します。 そのため、 Windows などでインストールされていない場合は、インストールして PATH を通しておく必要があります。
ファイル内の検索についても簡単に紹介しておきます。
通常のインクリメンタル検索は C-s です。これに C-u を付けた C-u C-s で正規表現によるインクリメンタル検索となります。
また、ファイル内の検索結果をリスト上に表示する occur コマンド(M-x occur)もあります。
Visual Studio
Visual Studio でも正規表現による検索は可能です。こちらは [編集] → [検索と置換] → [フォルダーを指定して検索] (Ctrl+Shift+F) などで検索ダイアログを出した後、オプションで正規表現を有効にします。

検索を実行すると検索結果のリストが表示されます。
このリストでダブルクリックや Enter キーを押すと結果位置にジャンプします。

[クイック検索](Ctrl+F)でも検索対象を変えることで、 同じ検索対象にすることができます。 ただし、動作に違いがあり、クイック検索では検索結果の位置に逐次移動していきます。
K2Editor
Windows のフリーのエディターとして K2Editor も上げておきます。私はコーディングには場合は Emacs を使ってますが、ちょっとテキストファイルを見たいといった場合にはこちらを使っています。
[検索] → [GREP] (Ctrl-G) などで検索ダイアログを出した後、正規表現にチェックを入れます。

検索を実行すると検索結果のリストが表示されます。 ただし、このリストはマウスのクリックでは結果位置の表示はできません。 [検索] → [タグジャンプ] ([F10]) でジャンプします。

通常の検索(Ctrl-F)でも、オプションで正規表現を使うことができます。

秀丸エディター
Windows のエディターとしては、秀丸エディターが有名です。 私はほとんど使ったことがないのですが、 無視もできないなということで、こちらの説明も入れておきました。[検索] → [grep の実行]のメニューから 検索ダイアログを出した後、正規表現にチェックを入れます。

検索を実行すると検索結果のリストが表示されます。 マウスのダブルクリックで結果位置へジャンプします。

通常の検索(Ctrl-F)でも、オプションで正規表現を使うことができます。
正規表現の歴史と方言
正規表現は Unix では ed といった初期のエディターから使われていましたが、 grep プログラムで広く使われるようになりました。その後、スクリプト言語の Perl で採用され、かなり拡張されます。 以降はこの Perl の正規表現がほぼ標準となったといってよく、 多くの言語やアプリで使われる正規表現は Perl の正規表現に合わせてあります。
紹介したエディターでは K2Editor は標準的な正規表現が使われています。
Emacs に関しては標準から外れた正規表現となっています。
また、 Emacs の grep コマンドは grep プログラムを実行します。 このため、 Emacs の他のコマンドや lisp のルールとも少しことなります。
Visual Studio は特に方言が強いです。 ただし、ここでの Visual Studio はエディターとしてのものです。
.NET, Boost の正規表現ライブラリといった VC++ などのコード内で使うものはそちらに従います。
秀丸エディターはバージョンによって変わってきます。
Ver. 8.13 以降はほぼ標準的な正規表現です。 それ以前は Emacs に近いルールとなっています。
このように正規表現にはアプリや言語によって書き方や使える機能に違いがあります。
そのため、この入門ではなるべく共通して使える機能だけに絞っています。 ただし、方言があるけど重要と思うものについてはその都度説明するようにしました。
次は ?
まずは英数字だけで検索を使ってみてください。 使っていくうちに、もっと検索結果を絞り込みたいと思ってくるはずです。例えばヘッダーのインクルードを見たくて、 include で検索したとき、関数名にもひっかかるといった具合です。
ここで、絞りこみをできるようにするのが正規表現です。
必要を感じると覚えやすくなります。必要性を感じながらーつーつルールを増やしていきましょう。
Step by step 正規表現入門 - 正規表現を使ったエディターでの置換
実際のコーディングで使うような例で説明した方が良さが伝わりやすいと思って、 C++ のサンプルを考えてみました。
置換のサンプル
まず、次のような列挙型の定義があったとします。enum FooType { FooA, FooB, FooC };こういった列挙型を使った switch 文を書くことはよくあります。例として列挙型を文字列でダンプ表示するための関数を作ります。 これを作るとき、列挙型定義をコピペして、正規表現で置換するとすぐに作れるようになります。
-
まず、ダンプ用関数の雛形を用意します。
std::ostream &operator<<(std::ostream &out, FooType val) { switch (val) { default: out << (static_cast<int>(val)) << " (Not FooType)"; } return out; }
-
列挙型定義の部分を貼り付けます。
std::ostream &operator<<(std::ostream &out, FooType val) { switch (val) { FooA, FooB, FooC default: out << (static_cast<int>(val)) << " (Not FooType)"; } return out; }
- 貼り付けた部分を置換します。
-
以下のような定義になって完成です。
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; |
ここでのグルーピングは前回の複数指定とは関係なく、取り出す文字列の指定のためだけのものです。
この () によるマッチ文字の取得はプログラミング時にもよく使われます。
() はパターンの複数指定よりもむしろマッチ文字の取得としての用途の方が重要だと思います。
置換後の文字列でマッチした文字列を取り出すには以下のメタ文字を使います。
\番号番号は () の出てきた順で、 \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 の場合は置換用のグルーピングは () ではなく、 {} を使います。
また、 ? は使えないので、 * で代用します。

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

連続して置換していくので、 [連続置換] の方のボタンをクリックして、置換していきます。
秀丸エディター
[検索] → [置換] (Ctrl-R) などで置換ダイアログを呼び出します。検索のときと同様に正規表現にチェックを入れておきます。

連続してするには、 [置換の前に確認] にチェックを入れて、 [全置換] をクリックします。
なお、秀丸はカーソル位置からの置換はできないので、サンプルはもっと絞ったパターンにしています。
欲張りマッチとものぐさマッチ
以下のような文章で強調文字を取得するパターン <em>(.*)</em> を使ったとします。<em>正規表現</em>は<em>便利</em>ですこの時マッチするのは "正規表現</em>は<em>便利" の文字です。
正規表現ではこのようになるべく長い文字列がマッチすることを欲張りマッチまたは最大マッチといい、 なるべく短くマッチすることをものぐさマッチまたは最小マッチといいます。
正規表現では通常は欲張りマッチとなっています。
欲張りマッチで余分なマッチをしてしまうことはよくありますが、 たいていパターンを工夫すれば解決できるので、入門としてはこれ以上詳しくは説明しません。
ただ、エディターによってはオプションで簡単に切り替えられるので、 用語としては覚えておくといいでしょう。
次は ?
置換を覚えて頻繁に書いていると空白を指定する [ \t] や変数用の [a-zA-Z0-9_] などを結構使います。 これを何度も書いていると結構めんどくさくなると思います。次はこれを楽に書く方法を紹介しましょう。