特集
» 2003年04月12日 00時00分 公開

基礎解説 スマートな文字列処理のための 正規表現入門(前編):― .NET Frameworkがサポートする正規表現クラスを徹底活用する ― (3/4)

[田口景介,著]

メタ文字

 それでは、.NET Frameworkの正規表現で利用できるメタ文字について解説していこう。これ以降の解説には、前述したregexコマンドと、そのソース・ファイルであるregex.csをサンプルに利用していく。

■通常文字

 まず、regexのソース・コードからコメント行を検索するパターンを考えてみよう。C#のコメントは、「/* 〜 */」や「// 〜」など複数の書式で記述できるが、リスト1ではさいわい「// 〜」しか使われていないので、単純に「//」が含まれている行を検索すれば、コメント行を見つけることができる。文字列定数内で「//」を使用していると、コメント行ではない行もコメント行として見付かってしまうが、見落としはないのでここではよしとしたい。

regex "//" regex.cs

検索例1:コメント行(「//」を含む行)の検索

  /// <summary>
  /// アプリケーションのメイン エントリ ポイントです。
  /// </summary>
        // ファイル名が指定されなかったときは標準入力から
        // 正規表現はRegexインスタンスに対して固定
          Match m = regex.Match(line);  // lineから検索
          if (m.Success) {              // 一致すればtrue

検索例1の実行結果

 いま指定した「//」のように、パターンにメタ文字が一切含まれていなければ、指定された文字列そのものの検索が行われる。文字列内から指定した文字列のインデックスを取得するString.IndexOfメソッドと同様な検索が行われるということだ。メタ文字と組み合わせた場合でも、メタ文字でない文字は、そのものとだけマッチする。.NET Frameworkの正規表現では、以下の文字がメタ文字として扱われるので、これ以外の文字はごく普通の比較が行われる。

. $ ^ { } [ ] ( ) | * + ? \
.NET Frameworkで使用されるメタ文字

 逆に、メタ文字として扱われる文字をそのものとして(通常の文字として)検索したければ、“¥”でエスケープしなければならない。例えば、「args[1]」という文字列を検索したいとしよう。このとき、以下のようにそのまま「args[1]」を指定すると、結果は何も表示されない。

regex "args[1]" regex.cs

検索例2:文字列「args[1]」を含む行の検索
この場合、検索結果は表示されない(どの行にもマッチングしない)。

 後で解説するように、“[ 〜 ]”は「角括弧で囲まれたいずれか1文字に一致する」正規表現である。つまり、「args1」を検索したことになってしまうからだ。

 正しく“args[1]”を見つけたければ、以下のように“[”と“]”を“¥”でエスケープしなければならない。

regex "args\[1\]" regex.cs

検索例3:文字列「args[1]」を含む行の正しい検索

          args[1], System.Text.Encoding.GetEncoding(932));

検索例3の実行結果

■[ 〜 ]

 ちょうど話が出たので、“[ 〜 ]”について解説しよう。前述したように、この角括弧は「指定した文字のいずれか1文字にマッチする」正規表現である。例えば、以下のように“[=!]”を指定すると「=」か「!」にマッチするため、“[=!]=”で「==」か「!=」を含む行を検索できる。

regex "[=!]=" regex.cs

検索例4:「==」か「!=」を含む行の検索

      } else if (args.Length == 1) {
      if (reader != null) {
        while ((line = reader.ReadLine()) != null) {

検索例4の実行結果

 この表現を利用すれば、“[0123456789]”として「任意の数字1文字」にマッチするパターンを表現できる。ただ、この調子で「任意のアルファベット」にマッチするパターンを表現しようとすれば、大文字小文字あわせて52文字もの文字を並べなければならなくなってしまう。そこで、1文字ずつ並べる代わりに、“[a-c]”のように文字の範囲を指定する書式も許されている。この書式を利用すれば「任意のアルファベットか数字1文字」にマッチするパターンを“[A-Za-z0-9]”のように簡潔に表現することができる(ハイフン自体をこれに含めたい場合には、角括弧内の先頭か末尾に“-”を記述すればよい)。

regex "[0-9]" regex.cs

検索例5:任意の数字1文字を含む行の検索

      if (args.Length < 1) {
      } else if (args.Length == 1) {
          args[1], System.Text.Encoding.GetEncoding(932));
        Regex regex = new Regex(args[0]);

検索例5の実行結果

 このように2通りの書式がある“[ 〜 ]”だが、このほかにも幾つか特殊なルールが決められている。

 メタ文字そのものを検索したければ、“¥”でエスケープしなければならないのはすでに述べたとおりだが、角括弧の中ではメタ文字が特殊な意味を失い、その文字自身としか一致しない通常の文字として扱われる。つまり、“[$*+]”と書けば「$」か「*」か「+」にしか一致しないのである(いずれもメタ文字)。従って、基本的に角括弧の中では、メタ文字であろうがなかろうが、1文字がそのもの1文字にしか一致しない。

regex "[([][0-9]" regex.cs

検索例6:「(」か「[」の後ろに数字がある行の検索

          args[1], System.Text.Encoding.GetEncoding(932));
        Regex regex = new Regex(args[0]);

検索例6の実行結果

 ただし、このルールにも例外がある。“¥”と“^”である。

 “¥”はメタ文字をエスケープする働き以外にも、C#などのプログラミング言語と同じく、正規表現でもコントロール・キャラクタを表すために利用される。“\n”は改行文字(0x0a)と、“\t”はタブ文字(0x09)と一致するという具合だ。

regex "\t\t\t\t\t" regex.cs

検索例7:5つ以上インデントされた行(5つのタブ文字含む行)の検索

          args[1], System.Text.Encoding.GetEncoding(932));
          Match m = regex.Match(line);  // lineから検索
          if (m.Success) {              // 一致すればtrue
            Console.WriteLine(line);
          }

検索例7の実行結果
:ページ構成の都合上、ここでは1つのタブ文字は、半角スペース2文字として掲載しています)

 これらエスケープ・キャラクタは角括弧の中でも解釈されるため、「そのもの1文字にマッチする」という原則に反して、“¥<文字>”の2文字で1文字にマッチすることになる。このため、“¥”を角括弧に含めたい場合は、“¥¥”としなければならない。

regex "[\t\\][a-z]" regex.cs

検索例8:タブか“¥”の後ろに英字がある行の検索

  static void Main(string[] args)  {
    try {
      if (args.Length < 1) {
        Console.Write("regex <RegularExpression> [<filesname>]\n");
        reader = Console.In;
        reader = new StreamReader(
          args[1], System.Text.Encoding.GetEncoding(932));
      if (reader != null) {
        string line;
        while ((line = reader.ReadLine()) != null) {
          if (m.Success) {              // 一致すればtrue
        reader.Close();
    catch (Exception e) {

検索例8の実行結果

 もう1つの例外が“^”である。まだ解説していないが、正規表現において“^”は「文字列の先頭」を表すメタ文字である。通常メタ文字は文字に一致するパターンとして利用されるが、“^”は文字ではなく、「先頭」という位置にマッチするという点で少々特殊なメタ文字である。なお、反対に「文字列の末尾」に一致するメタ文字として“$”が用意されている。

 ただし“^”が角括弧の中で、かつ“[”の直後で使われた場合には特別な意味を持つ。こうすると、角括弧の意味が「指定した文字に含まれていない任意の一文字」に変化する。例えば、“[^A-Za-z0-9]”とすれば、英数字以外の1文字にマッチするパターンとなる。“[ 〜 ]”の意味が逆転するわけだ。

regex "^[^\t]" regex.cs

検索例9:行頭がタブ文字でない行の検索

using System;
using System.Text.RegularExpressions;
using System.IO;
class Grep {
}

検索例9の実行結果

 なお、先頭以外で“^”が指定された場合は、ほかのメタ文字と同じく普通に“^”にだけマッチする文字として扱われる。

更新履歴

【2003/04/15】 “[ 〜 ]”内でのハイフンの取り扱いについて追記しました。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。