検索
特集

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

正規表現をうまく使いこなせば、数十行のコードにも匹敵するテキスト処理をたった数行で実現することも可能だ。今回はまず、正規表現の基礎について解説する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena

メタ文字

 それでは、.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.

ページトップに戻る