C#で正規表現を試すツールを作ってみた

最近、文字列を正規表現でいじっているのですが、なかなか一発で検索パターンが作れません。パターンを修正するたびにプロジェクトをビルドし直すのもどうかと思いまして、正規表現を試すツールを作ってみました。 作成した環境は下記です。

  • Visual Studio Express 2015 for Windows Desktop (C#)

目次

  1. アプリを作る
    1. シナリオ
    2. 文字列を保管するクラスを作る
    3. WPFでウインドウデザインをする
    4. 処理のコードを書く
  2. 試してみた

アプリを作る

世の中にはすでに同様のアプリが公開されてますので、正確で便利な操作を期待される場合は既存のアプリを使用される方が手っ取り早いです。

シナリオ

下記のような単純なアプリです。自分用です。 1. 検索対象の文字列をテキストボックスに入力する。 2. 正規表現のパターンをテキストボックスに入力する。 3. 実行ボタンをクリックする。 4. マッチした部分がテキストボックスに表示される。 151226-2-01 いろいろ便利機能を付けることも考えられますが、自分で使うだけのツールですので省略します。下記に注意です。

  • RegexOptions.Singlelineで検索しますので、正規表現で行頭行末を指定すると文字列全体の先頭末端になります。

  • 正規表現のパターン文字列の先頭にアットマークを付けないので、¥を使う場合は要注意です。

文字列を保管するクラスを作る

文字列を保管するためのクラスを作ります。 ソリューションエクスプローラーのプロジェクトを右クリックて、「追加」→「クラス」と選んでクラスを追加します。今回は、textContainer.csという名前にしました。 151226-2-02 textContainer.csを開いて、下記のようなクラスを記述します。クラスにする必要あるのかなと思うくらい単純です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace regex_check
{
    class textContainer
    {
        public string text { get; set; }
    }
}

WPFでウインドウデザインをする

フォームにツールボックスからTextBoxとButtonをドロップして、適当にレイアウトします。 151226-2-03 各コントロールのプロパティを変更します。

  • Windowのtitleを「regex_check」に変更

  • Buttonのcontentを「実行」に変更

  • 検索対象文字列を入力するテキストボックスの名前を「textBoxInput」に変更

  • 検索パターンを入力するテキストボックスの名前を「textBoxRegex」に変更

  • 検索結果を表示するテキストボックスの名前を「textBoxResult」に変更

  • テキストボックスtextBoxInputとtextBoxResultのAcceptsReturnにチェック(これをしないと、複数行のテキストをペーストしたときに最終行だけが表示されるようになったので。)

  • テキストボックスtextBoxInputとtextBoxResultのScrollViewer.CanContentScrollをチェック(縦スクロールバーの表示)

  • テキストボックスtextBoxInputとtextBoxResultのVerticalScrollBarVisibilityを「Auto」に変更(縦スクロールバーを自動で表示)

  • 各テキストボックスのTextWrappingを「Wrap」に変更

検索結果のオブジェクトをテキストボックスにバインドするために、textBoxResultのXAMLのtext部分を下記に変更します。

Text="{Binding Path=text}"

処理のコードを書く

ボタンのプロパティウインドウでclickイベントの入力欄をダブルクリックすると、ボタンのクリックイベント部が自動記述された状態でコードウィンドウが開きます。 151226-2-04 まず、正規表現を使うにはSystem.Text.RegularExpressionsをusing句に追加します。

using System.Text.RegularExpressions;

コードは下記のようにしました。入力のエラーチェックもしない極めて単純なコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace regex_check
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void buttonExect_Click(object sender, RoutedEventArgs e)
        {
            textContainer InputText = new textContainer();
            textContainer OutputText = new textContainer();

            InputText.text = textBoxInput.Text; // テキストボックスの入力内容を取り込む
            string pattern = textBoxRegex.Text; // テキストボックスの入力内容を取り込む

            try
            {
                OutputText.text = pattern + " でマッチ\r\n";
                // 正規表現で検索
                foreach (Match MatchedStrings in Regex.Matches(InputText.text, pattern, RegexOptions.Singleline))
                {
                    OutputText.text = OutputText.text + "\r\n"+ MatchedStrings.Value + "\r\n";
                }
            }
            catch
            {
                OutputText.text = "検索できませんでした。検索式を見直してください。";
            }
            textBoxResult.DataContext = OutputText; // テキストボックスに検索結果を表示する
        }
    }
}

試してみた

試してみました。 下記の文章から、#で始まる行だけを抜き出します。

# 知的財産の実態に迫る
東京特許許可局は実在する?
そこには驚愕の事実が!
## 関係者は語る
ほげほげほげ

検索パターンは下記にしました。Match()メソッドにRegexOptions.Singlelineと書かなければ、こんな面倒なパターンにはならないのですが。

(^|\n)#([^\n]*\n)+?

検索結果はこうなります。検索結果のテキストボックスが狭すぎて表示し切れていません。

(^|\n)#([^\n]*\n)+? でマッチ
# 知的財産の実態に迫る
## 関係者は語る

151226-2-05 RegexOptions.Singlelineオプションのオンオフの機能が必要かな。

公開日

広告