Step by step 正規表現入門 - ワイルドカード
これは *.txt や *.doc といったファイルのフィルターなどでよく使われます。
ワイルドカードは同じような用途に使え、ルールも簡単なので、言語やエディターで正規表現の代わりに使えるものも多いです。
ただ、そこでそのままワイルドカードを使うと、正規表現とルールが違うので次に繋がらなくなります。 ワイルドカード相当ものを正規表現で書けば、 今後正規表現のルールを少しづつ足していくことができます。
正規表現の次のステップとして、ワイルドカードを正規表現であらわすとどうなるかをやってみましょう。
ワイルドカードの特殊文字
ワイルドカードにも方言があって、 特殊文字もいろいろとありますが、 ここではよく使われる次の 2 つということにしておきましょう。特殊文字 | 機能 |
---|---|
* | 任意の文字列 |
? | 任意の 1 文字 |
*.cpp → foo.cpp, a.cpp, .cpp img???.jpg → img001.jpg, img002.jpg, imgbar.jpg
任意の 1 文字
? に相当する正規表現は、任意の 1 文字を表す .(ピリオド)です。この . のように文字そのものを指さず、特別な意味を持つものを正規表現ではメタ文字 やメタキャラクターと呼びます。
次にワイルドカードの * に対応するものは と行きたいところですが、残念ながら直接対応するものは正規表現にはありません。 その代わりに任意の 1 文字の . と繰り返し回数を組み合わせます。
繰り返し回数
繰り返し回数の指定のメタ文字は次の 3 つです。メタ文字 | 機能 |
---|---|
* | 0 回以上の繰り返し |
+ | 1 回以上の繰り返し |
? | 0 回または 1 回 |
a*bc → abc, aabc, bc a+bc → abc, aabc (bc はマッチしない) a?bc → abc, bcただし、 Visual Studio の正規表現では ? はありません。
ワイルドカードの * を正規表現で書くと .* となります。
エスケープ
. * + ? は正規表現ではメタ文字となりますがこの文字そのものを指定したいときがあります。この場合 \ を前に付けると文字そのものとなります。 このメタ文字の機能をなくすことをエスケープやクオートと呼びます。\ の文字自体を指定したい場合は \\ とします。
以上より *.cpp を正規表現になおすと .*\.cpp となります。
行頭、行末
*.cpp は .*\.cpp となると書きましたが、実は完全に同じではありません。というのも .*\.cpp は foo.cpp にも foo.cppy にもマッチするためです。 これを避けるために正規表現では、先頭と末尾となることを明示的に指定する必要があります。 これには以下の文字を使います。
メタ文字 | 意味 |
---|---|
^ | 行頭 |
$ | 行末 |
\ と英数字の組み合わせ
メタ文字の前に \ を付けるとエスケープですが、 逆に \ と英数字の組み合わせは特別な意味になります。この組みわせの正規表現のメタ文字は後で説明することにして、 プログラミングでも一般的に使われるものをまず紹介しておきます。
メタ文字 | 意味 |
---|---|
\t | タブ |
\n | 改行コード (LN) |
\r | 改行コード (CR) |
次は
ヘッダーのインクルード部分を include の文字だけで検索すると余分にヒットしました。 今回の知識を使って絞り込んでみましょう。ヒットさせたい行は次のような文です。
#include <foo/bar.h>そのための正規表現は "# で始まり、 include と .h を含む行" とします。
^\#.*include.+\.h任意文字のルールにより、だいぶん絞り込みが出来るようになりました。
次はこの任意文字をもっと細かく指定する方法に移りましょう。
Step by step 正規表現入門 - 文字クラスとグルーピング
文字クラス [ ]
例えば、SetStatus
と GetStatus
の両方を検索したいとき、
任意文字を使うと ?etStatus
となります。
ただこれだと余分なものまでにヒットします。ちゃんと S または G としたい場合には次のように書きます。
[SG]etStatusこのように [ ] は内部のどれかにマッチする文字となります。
正規表現で文字クラスといった場合にはこの [ ] で作ったものを指します。
範囲指定
[ ] 内では -(ハイフン)を使って範囲指定できます。マッチ例:
[a-d] → a, b, c, d [a-z] → 小文字のアルファベット a ~ z [0-9] → 0 ~ 9 の数字この範囲指定は文字コードの範囲を指定しているだけなので、 日本語対応していれば、 [あ-ん] のような記述も可能です。
排他指定
^を先頭に書いていると指定した文字以外の指定となります。[^ad] → a d 以外の文字 [^a-z] → 小文字のアルファベット以外。 A, 9 など
クラス内での特殊文字のエスケープ
[ ] 内では- ^] が特殊文字です。 これらをエスケープするにはそれぞれ次のように指定します。文字 | 記述法 | 例 |
---|---|---|
^ | 先頭以外に書く | [a^] |
- | 先頭または末尾に書く | [-a] [a-] |
] | 先頭に書く(^ よりは後) | []a] [^]a] |
また、 [は通常の文字で、 [a[] のように書きます。
+ * . などの記号をつかった正規表現のメタ文字も [ ] 内では、その字そのものになります。
ただし、 \ + 英数字はメタ文字となります。
[-+] → - または + [ \t\r\n] → 空白文字 (スペース、タブ、改行)
グルーピング ()
書かれた正規表現はよく パターン と呼ばれます。文字クラスは 1 文字の複数指定でしたが、 グルーピングは文字列やパターンをグループ化して複数指定する方法です。
グルーピングには () を使い、 | で複数指定にします。
例えば、以下は Error と Warning の両方の文字列にマッチする正規表現です。
(Error|Warning)また、画像ファイルなどのフィルターを正規表現で書くと次のようになります。
\.(png|gif|jpe?g)$ → .png .gif .jpeg .jpg
\ との組み合わせ
標準
正規表現では \ との組み合わせは基本的に以下のような方針になっています。文字 | 意味 |
---|---|
英数字 | 文字そのもの |
\ + 英数字 | メタ文字 |
記号 | メタ文字 |
\ + 記号 | 文字そのもの |
ただ、大抵は余分につけても問題ないので、 慣れないうちは記号を指定する場合には前に \ を書いておきましょう。
日本語の全角文字も文字そのものとなります。 英数字のように \ をつけてもメタ文字となることはありません。
Emacs の場合
前節の方針ですが、 Perl による拡張のため、 Emacs では記号の扱いに違いが出てきます。こちらでは基本的な記号以外は英数字と同じように 記号でも \ と組み合わせてメタ文字となります。 基本的な記号というのは、次のものです。
. * + ? ^ $ [ ]このため、()| もグルーピングとして使う場合には \を付ける必要があり、 つけてないとその文字そのものとなります。 これは他の正規表現と逆になっています。
Emacs の正規表現例:
\(Error\|Warning\) \.\(png\|gif\|jpe?g\)$ foo() → "foo()" の文字列にマッチ
まとめとサンプルパターン
ここまで出てきたルールを簡単にまとめてみます。文字 | 意味 |
---|---|
英数字 _ | 文字そのもの |
. | 任意の一文字 |
* | 0 回以上繰り返し |
+ | 1 回以上繰り返し |
? | 0 回または 1 回 |
\ | メタ文字のエスケープ |
[ ] | 括弧内の文字。 [ ] 内の - は範囲指定、 ^ はそれ以外の指定 |
( ) | | グルーピング |
(簡単にするために大文字小文字は区別せず、絞込みをゆるくしているところもあります)
対象 | 例 | パターン | 説明 |
---|---|---|---|
整数 | -100 | ^[+-]?[0-9]+$ |
+ - が先頭に付く可能性のある数字 |
実数 | +1.2 | ^[+-]?[0-9]+\.?[0-9]*$ |
整数の後に小数点以下の数字 |
カンマ付整数 | 10,000 | ^[+-]?[0-9]?[0-9]?[0-9](,[0-9][0-9][0-9])*$ |
, と数字の 3 回 のセットが 0 回以上繰り返す |
C 識別名 | st2i_k | ^[a-zA-Z_][a-zA-Z_0-9]*$ |
数字で始まらない英数字と_の文字列 |
メールアドレス | foo-bar@bar.co.jp | ^[a-z0-9._-]+@[a-z0-9._-]+$ |
途中で @ を含む英数字と . _ - の文字列 |
URL | http://yohshiy.blog.fc2.com/ | ^https?://([a-z0-9-]+\.)+[a-z0-9-./?%&=]*$ |
http:// または https:// で始まり、 英数字と -./?%&= の文字列 |
次は ?
ここまでの知識で正規表現の最小限のルールは身に付けたといってもいいでしょう。そこで今度はこれを使って正規表現による置換に入ります。
正規表現を便利だと思った方はまだ少ないかもしれませんが、 置換を使えるようになれば、便利さが実感できるのではないかと思います。