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 |
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 を意味する
|
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.
下記のリンクの記事にサンプルプログラムがありダウンロードできます.ソースコードも添付されています.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
実行例 |
|