Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2010年06月23日] [更新 2014年08月04日] Delphi サンプルプログラム集
   
952_Delphi で VBScript の正規表現
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro + vbscript.dll 5.8
952_VBScript_TRegExp.zip [2,312 KB] 2014年08月04日版(EXE同梱)







Delphi で VBScript の正規表現 - タイプライブラリの取り込み


Delphi で VBScript の正規表現を使用するための参考記事とサンプルです.

Delphi では,小宮秀一さん提供の Delphi 用の正規表現ユニット SkRegExp が利用できます.これは Delphi 2005 以降用となっています.また,Delpi XE では正規表現用のユニットが実装されました.したがって,本ページの記事は,主に Delphi 7 以前で正規表現を利用する際の参考です.ただし,動作確認は Delphi XE で行っています.
本ページのサンプルはマイクロソフト製の正規表現ライブラリを使う,ということになります.

この正規表現用のライブラリを利用するには,タイプライブラリの取り込みで,正規表現ライブラリ用のユニット VBScript_RegExp_55_TLB.pas を作成します.コンポーネントラッパーの作成はしますが,コンポーネントとして登録する必要はありません.ユニットの作成で構いません.



[備考]
VBScript 正規表現のリファレンスの日本語版が MSDN オンラインにありましたが,2014年08月04日現在ないようです..NET 関係のページにはあるようです.マイクロソフトのウェブページは本当によく移動や変更があります.
以下の記事を参考にしてくたさい.



  • 図1
  • タイプライブラリの取り込みで VBScript_RegExp_55_TLB.pas ファイルを作成




01_Test メソッドのテスト - 文字列の存在をチェック


VBScript の Test メソッドのテストです.Test メソッドは単に指定したパターンに一致する文字列が対象テキストにあるかを検出するだけです.



図2
設計時画面
図3
結果は False
  • ^ は先頭位置の文字列検索
図4
先頭の ^ を削除すれば True

リスト1
Test メソッドのテスト
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, VBScript_RegExp_55_TLB, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  テキスト内に指定文字列が存在するかをチェックするテスト
//
//  文字列'(シングルクォーテーション)使用の注意
//  文字として文字列中に書く場合は''と2つ続けて書く
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Edit1.Text := 'このプログラムはDelphiで作成されています';

  //検索条件(パターン)
  //対象文字列の先頭がDelphiかを検査(^がなければ文字列内の検索)
  Edit2.Text := '^Delphi';
end;

//=============================================================================
//  検索実行
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ARegExp : TRegExp;
  Flag    : Boolean;
begin
  ARegExp := TRegExp.Create(Self);
  try
    //大文字と小文字を区別しない
    ARegExp.IgnoreCase := True;
    //テキスト全てを対照に検索
    ARegExp.Global := True;
    //検索条件(パターン)
    ARegExp.Pattern := Edit2.Text;

    //実行
    Flag := ARegExp.Test(Edit1.Text);
    //結果を表示
    Label1.Caption := BoolToStr(Flag, True);
  finally
    FreeAndNil(ARegExp);
  end;
end;

end.




02_Replace メソッドのテスト - 文字列置換


Replace メソッドのテストプログラムです.正規表現で検索できたテキストを置換します.



図5
設計時画面
図6
実行結果例
図7
ハングル文字も置換可能
  • できないと韓国の人は困る (?)
  • 正規表現は Delphi|안녕
  • | は or を意味する

リスト2
文字列の置換
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, VBScript_RegExp_55_TLB, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  テキスト内の文字列置換テスト
//  Edit1.Text  対象のテキスト
//  Edit2.Text  その中の置換対象文字列パターン
//  Edit3.Text  この文字列に置換する
//
//  文字列'(シングルクォーテーション)使用の注意
//  文字として文字列中に書く場合は''と2つ続けて書く
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Edit1.Text := '你好Delphi2010안녕하세요叱鮭';

  //検索条件(パターン)
  //対象文字列の先頭がDelphiかを検査(^がなければ文字列内の検索)
  Edit2.Text := 'Delphi';

  Edit3.Text := 'DELPHI';
end;

//=============================================================================
//  置換実行
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ARegExp : TRegExp;
begin
  ARegExp := TRegExp.Create(Self);
  try
    //大文字と小文字を区別しない
    ARegExp.IgnoreCase := True;
    //テキスト全てを対照に検索
    ARegExp.Global := True;
    //置換対象文字列パターン
    ARegExp.Pattern := Edit2.Text;

    //置換して結果をTLabelに表示
    //Edit2.TextのパターンをEdit2.Textの文字列に置換
    Label1.Caption := ARegExp.Replace(Edit1.Text, Edit3.Text);
  finally
    FreeAndNil(ARegExp);
  end;
end;

end.




03_Replace メソッドのテスト -  HTML のタグ部分を削除


同じく Replace メソッドのテストですが,少し実用的にして,HTML テキストからタグを取り除いた部分,つまり,記事本文と思われる部分だけを取り出します.



図8
設計時画面
図9
実行例
  • 添付の HTML ファイルの場合
  • タグ部分が全て削除されている

リスト3
HTML ファイルのテキストからタグで囲まれた部分を削除
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, VBScript_RegExp_55_TLB, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    RichEdit1: TRichEdit;
    ComboBox1: TComboBox;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  HTMLファイルからテキスト部分のみを取得するテスト
//
//  文字列'(シングルクォーテーション)使用の注意
//  文字として文字列中に書く場合は''と2つ続けて書く
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  //テスト用の正規表現文字列をセット
  ComboBox1.Items.Clear;
  ComboBox1.Items.Add('<("[^"]*"|''[^'']*''|[^''">])*>'); //全てのタグを削除
  ComboBox1.Items.Add('<.+?>');                           //コメントは削除しない
  ComboBox1.Items.Add('<!--[\s\S]*?-->');                 //コメントだけ削除

  ComboBox1.ItemIndex := 0;
end;

//=============================================================================
//  TStringListのテキストから,コンボボックスで指定した置換条件(パターン)で,
//  テキスト内のタグを削除
//
//  添付以外のHTMLファイルもテスト可能なようにTOpenDialogでファイル選択
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ARegExp : TRegExp;
  SL      : TStringList;
begin
  OpenDialog1.Filter := 'HTMLファイル|*.htm;*.html';
  if OpenDialog1.InitialDir ='' then begin
    OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
  end;
  if not OpenDialog1.Execute then exit;

  RichEdit1.Clear;

  ARegExp := TRegExp.Create(Self);
  SL      := TStringList.Create;
  try
    //対象のテキストファイル(HTML)を読込む
    SL.LoadFromFile(OpenDialog1.FileName);

    //大文字と小文字を区別しない
    ARegExp.IgnoreCase := True;
    //テキスト全てを対照
    ARegExp.Global := True;
    //置換(検索)条件
    ARegExp.Pattern := ComboBox1.Text;

    //置換実行
    //指定パターンを空文字にする
    RichEdit1.Text := ARegExp.Replace(SL.Text, '');
  finally
    FreeAndNil(ARegExp);
    FreeAndNil(SL);
  end;
end;

end.




04_Execute メソッドのテスト - HTML のリンク URL 部分だけを取得


Execute メソッドのテストプログラムです.指定したパターンでテキストを検索してその情報のコレクションを取得します.ここでは HTML テキストファイルからリンクの URL 部分,リンクアドレスだけを抽出(取り出)します.



図10
設計時画面
図11
添付の HTML ファイルの結果

リスト4
リンクの URL アドレスだけを取り出す
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, VBScript_RegExp_55_TLB, ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Edit1: TEdit;
    Button1: TButton;
    RichEdit1: TRichEdit;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  HTMLテキストファイルからリンクのURL文字列のみを取得するテスト
//
//  フォームを表示したら,テスト用に検索パターン文字列をセット
//
//  文字列'(シングルクォーテーション)使用の注意
//  文字として文字列中に書く場合は''と2つ続けて書く
//
//  TComboBoxに文字列をセットしてテストしたが,TCombBoxのTextプロパティを
//  TRegExp.Patternに代入して実行すると,OLEエラーになることがある
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Edit1.Text := '<a\s+href=["'']*([^>"'']*)["'']*(.*?)</a>';
end;

//=============================================================================
//  TStringListのテキストから,指定パターン(文字列)のマッチ(一致)情報を取得
//  その後,後方参照(円弧の括弧で囲んだ部分)の結果を取り出して表示
//
//  添付以外のHTMLファイルもテスト可能なようにTOpenDialogでファイル選択
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ARegExp     : TRegExp;
  ACollection : MatchCollection;
  AMatch      : Match;
  ASubMatches : SubMatches;
  SL          : TStringList;
  i           : Integer;
begin
  OpenDialog1.Filter := 'HTMLファイル|*.htm;*.html';
  if OpenDialog1.InitialDir ='' then begin
    OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
  end;
  if not OpenDialog1.Execute then exit;

  RichEdit1.Clear;

  ARegExp := TRegExp.Create(Self);
  SL      := TStringList.Create;
  try
    //対象のテキストファイル(HTML)を読込む
    SL.LoadFromFile(OpenDialog1.FileName);

    //大文字と小文字を区別しない
    ARegExp.IgnoreCase := True;
    //テキスト全てを対照
    ARegExp.Global := True;

    //検索条件(パターン)
    ARegExp.Pattern := Edit1.Text;

    //バターンにマッチした情報をSL.textから取得
    ACollection := ARegExp.Execute(SL.Text) as MatchCollection;

    //その情報を順番に取り出す
    if ACollection.Count > 0 then begin
      for i := 0 to ACollection.Count - 1 do begin
        AMatch      := ACollection.Item[i] as Match;
        //AMatch.Valueでマッチした文字列の取得可能
        //後方参照の結果を取り出す
        ASubMatches := AMatch.SubMatches as SubMatches;
        //後方参照の結果文字列
        RichEdit1.Lines.Add(ASubMatches.Item[0]);
      end;
    end else begin
      ShowMessage('指定パターンの検出に失敗しました.');
    end;
  finally
    FreeAndNil(ARegExp);
    FreeAndNil(SL);
  end;
end;

end.




05_サンプルアプリケーション


下記のリンクの記事にサンプルプログラムがありダウンロードできます.ソースコードも添付されています.Windows 7 + Delphi 7 Pro, XE(UP1) Pro で利用できることを確認しました.
そのページの記事では VBScript_RegExp_55_TLB.pas の修正コードが掲載されていますが,本ページの動作確認環境で作成したユニットであれば必要ありません.

下図は,このプロジェクトの実行例です.記事にある,以下のサンプルテキストを実行しています.(この正規表現を上のサンプルの HTML テキストに対して実行すると失敗します).


// 対象文字列
<a href="http://www.borland.co.jp/">日本ボーランド</a>
<a href="http://www.google.co.jp/">Google</a>

// 正規表現
<a\s+href=["'']*([^>"'']*)["'']*>(.*?)</a>



図12
プロジェクトを起動
図13
実行例