【やさしいC#】lesson9.4 ファイルの応用と正式表現

C#

タブにファイルを表示する

  ファイルを使ったプログラムを応用してみることにしましょう。次のプログラムをみてください。

//sample8.cs
using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO;

namespace lesson9
{
    class sample8 : Form
    {
        private PictureBox[] pb;
        private TabControl tc;
        private TabPage[] tp;
        static void Main(string[] args)
        {
            Application.Run(new sample8());
        }
        public sample8()
        {
            this.Text = "lesson9"; this.Width = 600; this.Height = 400;

            tc = new TabControl();

            string dir = @"D:\";//指定したディレクトリについて
            string[] fls = Directory.GetFiles(dir, "*.bmp");//ファイルのリストを得ます(①)

            pb = new PictureBox[fls.Length];
            tp = new TabPage[fls.Length];//②該当ファイル数のタブページを準備します

            for (int i = 0; i < fls.Length; i++)
            {
                pb[i] = new PictureBox();
                tp[i] = new TabPage(fls[i]);

                pb[i].Image = Image.FromFile(fls[i]);
                tp[i].Controls.Add(pb[i]);//③タブページに画像を追加します
                tc.Controls.Add(tp[i]);//④タブコントロールにタブページを追加します。
            }

            tc.Parent = this;
        }
    }
}
実行画面

  このプログラムでは、指定したディレクトリにおいて拡張子がBMPである画像ファイルを、タブを表すタブコントロール(TabControl)に表示します。
  まず、ディレクトリ中のファイルを得るためにに、DirectoryクラスのGetFiles()メソッドを使用します(①)。ファイルを得る際にはBMPファイルだけ絞り込みます。得られたファイル数だけ、それぞれのタブのページを表すタブページ(TabPage)を用意します(②)。
  次に、タブページに画像を読み込んだピクチャボックスを追加します(③)。さらにこのタブページを、タブコントロールに追加するのです(④)。

子フォームにファイルを表示する

  もう1つ、ファイルの内容を表示するプログラムを作成しましょう。今度は指定したディレクトリにおいて拡張子がxmlであるファイル内容を表示します。

using System;
using System.Windows.Forms;
using System.IO;

namespace lesson9
{
    class sample9 : Form
    {
        private ChildForm[] cf;
        static void Main(string[] args)
        {
            Application.Run(new sample9());
        }
        public sample9()
        {
            this.Text = "lesson9"; this.Width = 600; this.Height = 400;
            this.IsMdiContainer = true;

            string dir = @"D:\";//指定したディレクトリについて
            string[] fls = Directory.GetFiles(dir, "*.xml");//ファイルのリストを得ます(①)

            cf = new ChildForm[fls.Length];//該当ファイル数の子フォームの配列を準備します

            for (int i = 0; i < fls.Length; i++)
            {
                cf[i] = new ChildForm(fls[i]);//子フォームを作成します
                cf[i].MdiParent = this;//①子フォームの親をこのフォームとします
                cf[i].Show();//②子フォームを表示します
            }
        }
    }
    class ChildForm : Form//子フォームを定義します
    {
        TextBox tb;
        public ChildForm(string name)
        {
            this.Text = name;
            
            tb = new TextBox();
            tb.Multiline = true;tb.Width = this.Width;tb.Height = this.Height;

            StreamReader sr = new StreamReader(name, System.Text.Encoding.Default);
            tb.Text = sr.ReadToEnd();//テキストボックスにファイル内容を読み込みます
            sr.Close();

            tb.Parent = this;
        }
    }
}
実行画面

  ここではディレクト内のXMLファイルを表示するに、親フォームの中に子フォームを表示してます。このようなウィンドの事をMDI(multiple document interface)とも呼びます。
  子フォームのMdiParentプロパティに親フォームを指定し(①)、子フォームを表示することで(②)でMDIフォームを作成することができます。
  同じディレクトリ内に複数のXMLファイルが存在した場合には、複数の子フォームが表示されますので、確かめててください。

文字列を置換する

  ファイルの内容を取り扱うプログラムを見てみましょう。テキストファイルやXMLファイルなどを扱う場合には、文字列の検索や置換ができると便利です。検索・置換を行うために、System.Text.Regular.Expressions名前空間正規表現(Regex)クラスを使うことができます。
  単純にすべての単語を置換から行ってみることにしましょう。

using System;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;

namespace lesson9
{
    class sample10 : Form
    {
        private Label[] lb = new Label[3];
        private TextBox[] tb = new TextBox[3];
        private Button bt;
        private TableLayoutPanel tlp;
        static void Main(string[] args)
        {
            Application.Run(new sample10());
        }
        public sample10()
        {
            this.Text = "lesson9"; this.Width = 600; this.Height = 400;

            for (int i = 0; i < lb.Length; i++)
            {
                lb[i] = new Label();
                lb[i].Dock = DockStyle.Fill;
            }
            for (int i = 0; i < tb.Length; i++)
            {
                tb[i] = new TextBox();
                tb[i].Dock = DockStyle.Fill;
            }

            bt = new Button();

            tlp = new TableLayoutPanel();
            tlp.ColumnCount = 2;
            tlp.RowCount = 5;
            tlp.Dock = DockStyle.Fill;

            lb[0].Text = "入力してください";
            tlp.SetColumnSpan(lb[0], 2);

            tb[0].Multiline = true;
            tb[0].Height = 100;
            tlp.SetColumnSpan(tb[0], 2);

            lb[1].Text = "置換前";
            lb[2].Text = "置換後";
            bt.Text = "置換";
            tlp.SetColumnSpan(bt, 2);

            lb[0].Parent = tlp;
            tb[0].Parent = tlp;
            lb[1].Parent = tlp;
            tb[1].Parent = tlp;
            lb[2].Parent = tlp;
            tb[2].Parent = tlp;
            bt.Parent = tlp;

            tlp.Parent = this;

            bt.Click += new EventHandler(bt_Click);

        }
        public void bt_Click(Object sender, EventArgs e)
        {
            Regex rx = new Regex(tb[1].Text);
            tb[0].Text = rx.Replace(tb[0].Text, tb[2].Text);
        }

    }
}
実行画面

  プログラムを実行しテキストボックスにテキスト入力してください。さらに置換前の文字列と置換後の文字列を入力し、「置換」ボタンを押します。すると指定した文字置換前文字列が置換後の文字列に全て置換されます。
  このプログラムでは、まず置換する箇所を特定するため、置換前の文字列をパターンとして指定してRegexクラスのオブジェクトを作成します。これで置換前文字別パターンと一致箇所を調べるオブジェクトを得ることができます。
  実際に置換を行うには、Replace()メソードを使います。対象となる文章について、置換前文字列と一致した部分を、置換後文字列で置き換えます。

文字列を検索する

  次に検索を行ってみましょう。検索にマッチした文字を赤色に変更することにします。

using System;
using System.Windows.Forms;
using System.IO;
using System.Drawing;
using System.Text.RegularExpressions;

namespace lesson9
{
    class sample11 : Form
    {
        private Label lb;
        private RichTextBox rt;
        private TextBox tb;
        private Button bt;
        private TableLayoutPanel tlp;
        static void Main(string[] args)
        {
            Application.Run(new sample11());
        }
        public sample11()
        {
            this.Text = "lesson9"; this.Width = 300; this.Height = 300;

            lb= new Label();
            lb.Dock = DockStyle.Fill;

            rt = new RichTextBox();
            rt.Dock = DockStyle.Fill;


            tb = new TextBox();
            tb.Dock = DockStyle.Fill;

            bt = new Button();

            tlp = new TableLayoutPanel();
            tlp.ColumnCount = 2;
            tlp.RowCount = 3;
            tlp.Dock = DockStyle.Fill;

            lb.Text = "入力してください";
            tlp.SetColumnSpan(lb, 2);

            rt.Multiline = true;
            rt.Height = 100;
            tlp.SetColumnSpan(rt, 2);

            bt.Text = "検索";
            tlp.SetColumnSpan(bt, 2);

            lb.Parent = tlp;
            rt.Parent = tlp;
            tb.Parent = tlp;
            bt.Parent = tlp;

            tlp.Parent = this;

            bt.Click += new EventHandler(bt_Click);

        }
        public void bt_Click(Object sender, EventArgs e)
        {
            Regex rx = new Regex(tb.Text);//検索文字列を指定します
            Match m = null;
            for (m = rx.Match(rt.Text); m.Success; m = m.NextMatch())//対象文字列について検索を行い
            {
                rt.Select(m.Index, m.Length);
                rt.SelectionColor = Color.Red;//検索が成功したら範囲を選択して赤色にします
            }
        }

    }
}
実行画面

  上部のテキストボックスにテキスト入力してください。下部のテキストボックスに検索文字列を入力し、「検索」ボタンを押します。すると指定した文字列が赤色で表示されます。
  テキストの検索を行うには、RegexクラスのMatch()メソードで検索を行い、Successプロパティを調べます。Successプロパティーの値がTrueである限りはNextMatch()メソードで検索を続けます。
  文字色を変更するために、リッチテキストボックス(RichTextBox)コントロールを使っています。検索単語見つかるたびにマッチした範囲の選択を行い、文字の選択色を変更しています。

rt.Select(m.Index, m.Length);//マッチした範囲を選択します
rt.SelectionColor = Col
or.Red;//選択色を変更します

正式表現の仕組みを知る

  ここでRegexクラスを使う表現について詳しくみておきましょう。Regexのオブジェクトを作成するときに指定するパターンには正規表現(regular expression)と呼ばれる表現を使うことができます。正規表現は、通常の文字と次のようなメタ文字を使って表現されます。

メタ文字意味
^行頭
$行末
.任意の1文字
[]文字クラス
*0回以上
+1回以上
?0または1
{a}a回
{a,}a回以上
{a,b}a~b回
主なメタ文字

  ^(キャレット、ハット)は行頭を表します。例えば「^CSharp」というパターンは、「CSharp」「CSharpp」という文字列にマッチします。「CCSharp」や「CCCSharp」にはマッチしません。
  $は行末を表します。例えば「CSharp$」というパターンには、「CSharp」「CCSharp」という文字列にマッチします。「CSharpp」や「CSharppp」にはマッチしません。
  文字クラスは次のように使うことができます。

パターンパターンの意味マッチする文字列の例
[012345]012345のいずれか3
[0-9]0~9のいずれか5
[A-Z]A~ZのいずれかB
[A-Za-z]A~Z、a~zのいずれかb
[^012345]012345ではない文字6
[01][01]00, 01,10,11のいずれか01
[A-Za-z][0-9]アルファベット1つに数字が1つ続くA0

外部プログラムを起動す

  最後に、外部のプログラムを簡単に起動する方法を紹介しましょう。ここではファイル名を指定して関連づけられたプログラムを起動できるようにします。

using System;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;


namespace lesson9
{
    class sample12:Form
    {
        private ListBox lbx;
        private Button bt;
        static void Main(string[] args)
        {
            Application.Run(new sample12());
        }
        public sample12()
        {
            this.Text = "lesson9"; this.Width = 600; this.Height = 300;

            string dir = "E:\\099_Technology\\C#\\csharp\\csharp_train";
            string[] name = Directory.GetFiles(dir);

            lbx = new ListBox();
            lbx.Dock = DockStyle.Top;

            for (int i = 0; i < name.Length; i++)
            {
                lbx.Items.Add(name[i]);
            }

            bt = new Button();
            bt.Text = "起動";
            bt.Dock = DockStyle.Bottom;

            lbx.Parent = this;
            bt.Parent = this;

            bt.Click += new EventHandler(bt_Click);
        }
        public void bt_Click(object sender, EventArgs e)
        {
            string name = lbx.SelectedItem.ToString();

            if (name != null)
            {
                Process.Start(@name);
            }
        }
    }
}
実行画面
ListBoxのIndexを選択し、「起動」ボタンを押して、こちらの画面が表示される

  プログラムを実行すると、リストボックスにファイル名が表示されます。
  ここでリストボックス中の画像ファイル名を選択し、「起動」ボタンを押すと、外部プログラムである画像ビューアが起動します。また、OS上でソースファイルをテキストエディタに関連付けている場合には、外部のテキストエディタが起動します。
  なお、@を文字列の先頭につけると、ディレクトリの区切り記号である\などの文字を、エスケープシーケンスを使わずに表すことができます。

クラス説明
System.Diagnostics.Processクラス
static Process Start(string str)メソッド指定した文書を関連づけられた外部プログラムで起動する

コメント

タイトルとURLをコピーしました