天天看點

Delphi 正規表達式文法

在 Delphi 中使用正規表達式, 目前 PerlRegEx 應該是首選, 準備徹底而細緻地研究它.

官方網站: http://www.regular-expressions.info/delphi.html

直接下載下傳: http://www.regular-expressions.info/download/TPerlRegEx.zip

安裝方法:

1、先把解壓的 TPerlRegEx 檔案夾放一個合适的地方, 我放在了 Delphi 的 Imports 目錄中.

2、目前最新 For Win32 的版本是對 Delphi 2006 的, 2007 也能用. 

    打開 PerlRegExD2006.dpk, 提示缺少資源檔案, 沒關系; 

    在 Project Manager 視窗中的 PerlRegExD2006.bpl 上點選右鍵, 執行 Install;

    這時在 Tool Palette 的清單中已經有了 TPerlRegEx, 在 JGsoft 組.

3、Tools -> Options -> Environment Options -> Delphi Options -> Library-Win32 -> Library path -> 

    添加路徑: .../Imports/TPerlRegEx

4、可以使用了! 直接 uses PerlRegEx 或從 Tool Palette 添加都可以.

    如果不喜歡 Tool Palette 的添加方式可以省略第二步.

計劃的學習步驟: 1、正則文法; 2、TPerlRegEx 功能.

//準備用這段簡單的代碼測試文法:
uses
PerlRegEx; //uses 正規表達式單元

procedure TForm1.FormCreate(Sender: TObject);
var
reg: TPerlRegEx; //聲明正規表達式變量
begin
reg := TPerlRegEx.Create(nil); //建立

reg.Subject := 'sSsS';    //這是要替換的源字元串
  reg.RegEx   := 's';       //這是表達式, 在這裡是準備替換掉的子串
  reg.Replacement := '◆';  //要替換成的新串
  reg.ReplaceAll;           //執行全部替換

ShowMessage(reg.Subject); //傳回替換結果: ◆S◆S

FreeAndNil(reg); //因為建立時屬主給了 nil, 這裡沒有使用 reg.Free
end;

        
Delphi 正規表達式文法(1): 關于大小寫與中文
//替換一般字元串
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '我愛DELPHI, 但Delphi不愛我!';
            reg.RegEx   := 'Delphi';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 我愛DELPHI, 但◆不愛我!
            
            FreeAndNil(reg);
            end;
            
       
            //不區分大小寫
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '我愛DELPHI, 但Delphi不愛我!';
            reg.RegEx   := 'Delphi';
            reg.Replacement := '◆';
            reg.Options := [preCaseLess]; //不區分大小的設定, 預設是區分的
              reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 我愛◆, 但◆不愛我!
            
            FreeAndNil(reg);
            end;
            
       
            //試試中文替換
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '我愛DELPHI, 但Delphi不愛我!';
            reg.RegEx   := '我';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆愛DELPHI, 但Delphi不愛◆!
            
            FreeAndNil(reg);
            end;
            
       
            //如果不區分大小寫, 竟然也不區分中文字了
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '我愛DELPHI, 但Delphi不愛我!';
            reg.RegEx   := '我';
            reg.Replacement := '◆';
            reg.Options := [preCaseLess]; //也設定不區分大小
              reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆◆DELPHI, ◆Delphi◆◆◆!
            
            FreeAndNil(reg);
            end;
            //我測試了不同的漢字, 除了亂以外,沒有規律; 所有如果操作漢字暫時不要指定 preCaseLess
                  
Delphi 正規表達式文法(2): 或者與重複
// | 号的使用, | 是或者的意思
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'CodeGear Delphi 2007';
            reg.RegEx   := 'e|Delphi|0'; //使用了 | 記号
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: Cod◆G◆ar ◆ 2◆◆7
            
            FreeAndNil(reg);
            end;
            
       
            // + 的使用, + 是重複 1 個或多個
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'ab+'; //使用了 + 記号, 這裡是允許 a 後面有 1 個或多個 b
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: a aa aaa aaaa ◆ ◆ ◆a a呀a
            
            FreeAndNil(reg);
            end;
            
       
            // * 的使用, * 是重複 0 個或多個
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'ab*'; //使用了 * 記号, 這裡是允許 a 後面有多個或者沒有 b
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆ ◆◆ ◆◆◆ ◆◆◆◆ ◆ ◆ ◆◆ ◆呀◆
            
            FreeAndNil(reg);
            end;
            
       
            // ? 的使用, ? 是重複 0 個或 1 個
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'a?'; //使用了 ? 記号
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆ ◆◆ ◆◆◆ ◆◆◆◆ ◆b ◆bb ◆bbb◆ ◆呀◆
            
            FreeAndNil(reg);
            end;
            
       
            //大括号的使用<1>, 指定重複數
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'a{3}'; //這裡指定重複 3 次
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: a aa ◆ ◆a ab abb abbba a呀a
            
            FreeAndNil(reg);
            end;
            
       
            //大括号的使用<2>
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'a{2,4}'; //這裡指定重複 2-4 次
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: a ◆ ◆ ◆ ab abb abbba a呀a
            
            FreeAndNil(reg);
            end;
            
       
            //大括号的使用<3>
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'a aa aaa aaaa ab abb abbba a呀a';
            reg.RegEx   := 'a{1,}'; //n 個或多個, 這裡是 1 個或多個
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆ ◆ ◆ ◆ ◆b ◆bb ◆bbb◆ ◆呀◆
            
            FreeAndNil(reg);
            end;
            //上面這個 {1,} 和 + 是等效的;
            //還有 {0,1} 與 ? 是等效的;
            //{0,} 和 * 是等效的      

Delphi 正規表達式文法(3): 比對範圍

// [A-Z]: 比對所有大寫字母
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[A-Z]';
reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆ode◆ear ◆elphi 2007 for ◆in32

FreeAndNil(reg);
end;

   
// [a-z]: 比對所有小寫字母
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[a-z]';
reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: C◆◆◆G◆◆◆ D◆◆◆◆◆ 2007 ◆◆◆ W◆◆32

FreeAndNil(reg);
end;

   
// [0-9]: 比對所有數字
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[0-9]';
reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: CodeGear Delphi ◆◆◆◆ for Win◆◆

FreeAndNil(reg);
end;

   
//比對幾個範圍
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[C-Do-p0-2]'; //大寫字母: C-D; 小寫字母: o-p; 數字: 0-2
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆◆deGear ◆el◆hi ◆◆◆7 f◆r Win3◆

FreeAndNil(reg);
end;

   
//比對 [] 中的所有
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[Ci2]'; //大寫字母: C; 小寫字母: i; 數字: 2
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆odeGear Delph◆ ◆007 for W◆n3◆

FreeAndNil(reg);
end;

   
// ^ 排除 [] 中的所有
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'CodeGear Delphi 2007 for Win32';
reg.RegEx   := '[^Ci0-2]'; //這裡排除了大寫字母: C; 小寫字母: i; 數字: 0-2
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: C◆◆◆◆◆◆◆◆◆◆◆◆◆i◆200◆◆◆◆◆◆◆i◆◆2

FreeAndNil(reg);
end;      
Delphi 正規表達式文法(4): 常用轉義字元與 .
// /d 比對所有數字, 相當于 [0-9]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/d';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 期待Delphi ◆◆◆◆ for Win◆◆!
            
            FreeAndNil(reg);
            end;
            
          
            // /D 比對所有非數字, 相當于 [^0-9]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/D';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆◆◆◆◆◆◆◆◆◆◆2008◆◆◆◆◆◆◆◆32◆◆
            
            FreeAndNil(reg);
            end;
            
          
            // /w 比對字母、數字與下劃線_, 相當于 [A-Za-z0-9_]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/w';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 期待◆◆◆◆◆◆ ◆◆◆◆ ◆◆◆ ◆◆◆◆◆!
            
            FreeAndNil(reg);
            end;
            
          
            // /W 比對非字母、數字與下劃線_, 相當于 [^A-Za-z0-9_]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/W';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 期待◆◆◆◆◆◆ ◆◆◆◆ ◆◆◆ ◆◆◆◆◆!
            
            FreeAndNil(reg);
            end;
            
          
            // /s 比對任何空白, 包括空格、制表、換頁等, 相當于 [/f/n/r/t/v]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/s';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: 期待Delphi◆2008◆for◆Win32!
            
            FreeAndNil(reg);
            end;
            {
            /f : 換頁符
            /n : 換行符
            /r : 回車符
            /t : 制表符(Tab)
            /v : 垂直制表符
            }
            
          
            // /S 比對任何非空白, 相當于 [^/f/n/r/t/v]
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待Delphi 2008 for Win32!';
            reg.RegEx   := '/S';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: ◆◆◆◆◆◆◆◆◆◆ ◆◆◆◆ ◆◆◆ ◆◆◆◆◆◆◆
            
            FreeAndNil(reg);
            end;
            
          
            // /x 比對十六進制的 ASCII
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := 'CodeGear Delphi';
            reg.RegEx   := '/x61'; // a 的 ASCII 值是 97, 也就是十六進制的 61
              reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject); //傳回: CodeGe◆r Delphi
            
            FreeAndNil(reg);
            end;
            //非常遺憾 TPerlRegEx 不能使用 /u 或 /U 比對 Unicode 字元!
            
           
            // . 比對除換行符以外的任何字元
            var
            reg: TPerlRegEx;
            begin
            reg := TPerlRegEx.Create(nil);
            reg.Subject := '期待' + #10 + 'Delphi 2008 for Win32!'; //#10是換行符
              reg.RegEx   := '.';
            reg.Replacement := '◆';
            reg.ReplaceAll;
            ShowMessage(reg.Subject);
            {傳回:
            ◆◆◆◆
            ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
            }
            FreeAndNil(reg);
            end;      

Delphi 正規表達式文法(5): 邊界

// /b 單詞邊界
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := '/bDelphi/b'; //前後邊界
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆ Delphi2007 MyDelphi

FreeAndNil(reg);
end;

  
// /b 單詞邊界: 左邊界
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := '/bDelphi'; //左邊界
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆ ◆2007 MyDelphi

FreeAndNil(reg);
end;

  
// /b 單詞邊界: 右邊界
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := 'Delphi/b'; //右邊界
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆ Delphi2007 My◆

FreeAndNil(reg);
end;

  
// /B 非單詞邊界
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi MyDelphi2007 MyDelphi';
reg.RegEx   := '/BDelphi/B'; //現在隻有 MyDelphi2007 中的 Delphi 屬于非單詞邊界
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: Delphi My◆2007 MyDelphi

FreeAndNil(reg);
end;

  
// ^ 行首
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := '^Del'; //比對在行首的 Del
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆phi Delphi2007 MyDelphi

FreeAndNil(reg);
end;

  
// /A 也标記行首
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := '/ADel'; //比對在行首的 Del
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: ◆phi Delphi2007 MyDelphi

FreeAndNil(reg);
end;

  
// $ 行尾
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := 'phi$'; //比對在行尾的 phi
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: Delphi Delphi2007 MyDel◆

FreeAndNil(reg);
end;

  
// /Z 也标記行尾
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'Delphi Delphi2007 MyDelphi';
reg.RegEx   := 'phi/Z'; //比對在行尾的 phi
  reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); //傳回: Delphi Delphi2007 MyDel◆

FreeAndNil(reg);
end;
// 測試時, /Z 不區分大小寫; /A 區分

    
     Delphi 正規表達式之TPerlRegEx 類的屬性與方法(6): EscapeRegExChars 函數 
    

       
// EscapeRegExChars 函數可以自動為特殊字元加轉義符号 /
var
reg: TPerlRegEx;
begin
reg := TPerlRegEx.Create(nil);
reg.Subject := 'C++Builer';
reg.RegEx   := reg.EscapeRegExChars('C+') + '{2}'; {相當于 'C/+{2}'}
reg.Replacement := '◆';
reg.ReplaceAll;
ShowMessage(reg.Subject); {傳回: ◆Builer}
FreeAndNil(reg);
end;      
Delphi 正規表達式之TPerlRegEx 類的屬性與方法(7): Split 函數 
      
       
//字元串分割: Split
var
reg: TPerlRegEx;
List: TStrings;
begin
List := TStringList.Create;
reg := TPerlRegEx.Create(nil);
reg.Subject := 'aaa,bbb,ccc,ddd';
reg.RegEx   := ','; {這裡可是運作相當複雜的分割符啊}
reg.Split(List,MaxInt); {第一個參數讀入的是 Subject; 第二個參數是分成多少份}
{ 輸入一個最大整數, 表示能分多少就分多少}
ShowMessage(List.Text);
{傳回:
aaa
bbb
ccc
ddd
}
FreeAndNil(reg);
List.Free;
end;