zoukankan      html  css  js  c++  java
  • 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 ->
        添加路径:
    ...ImportsTPerlRegEx

    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); //或 reg.Free
    end;
    
    
    //替换一般字符串
    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
    
    
    // | 号的使用, | 是或者的意思
    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,} 和 * 是等效的
    
    
    // [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;
    
    
    // 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); //返回: ◆◆◆◆Delphi◆2008◆for◆Win32◆◆
    
      FreeAndNil(reg);
    end;
    
    
    // s 匹配任何空白, 包括空格、制表、换页等, 相当于 [f
    
    	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 : 换页符
      
     : 换行符
      
     : 回车符
      	 : 制表符(Tab)
      v : 垂直制表符
    }
    
    
    // S 匹配任何非空白, 相当于 [^f
    
    	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;
    
    
    //  单词边界
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi Delphi2007 MyDelphi';
      reg.RegEx   := 'Delphi'; //前后边界
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆ Delphi2007 MyDelphi
    
      FreeAndNil(reg);
    end;
    
    
    //  单词边界: 左边界
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi Delphi2007 MyDelphi';
      reg.RegEx   := 'Delphi'; //左边界
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆ ◆2007 MyDelphi
    
      FreeAndNil(reg);
    end;
    
    
    //  单词边界: 右边界
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi Delphi2007 MyDelphi';
      reg.RegEx   := 'Delphi'; //右边界
      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   := 'BDelphiB'; //现在只有 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;
    
    
    //  也标记行尾
    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;
    // 测试时,  不区分大小写; A 区分
    
    
    //贪婪匹配
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '内容';
      reg.RegEx   := '<.*>'; //将会全部匹配, 因为两头分别是: < 和 >
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆
    
      FreeAndNil(reg);
    end;
    
    
    //非贪婪匹配
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '内容';
      reg.RegEx   := '<.*?>'; // *? 是非贪婪匹配方法之一, 将匹配每组 <>
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆◆◆标题◆◆◆内容◆◆
    
      FreeAndNil(reg);
    end;
    
    //更多贪婪与非贪婪匹配对照: 
    
     
     贪婪匹配   非贪婪匹配  描述 
    ? ?? 0 个或 1 个 
    + +? 1 个或多个 
    * *? 0 个或多个 
    {n} {n}? n 个 
    {n,m} {n,m}? n - m 个 
    {n,} {n,}? n 个或多个 
    
    
    // ? 号的意义是匹配 0-1 次, 如果需要匹配 ? 怎么办
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '你好吗? 还行!';
      reg.RegEx   := '?|!'; // 加转义用的 
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: 你好吗◆ 还行◆
    
      FreeAndNil(reg);
    end;
    
    
    //乱用转义符号  有时是可以的, 但有时会出问题, 最好不要乱用
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '你好吗? 还行!';
      reg.RegEx   := '?|!|好'; // 给没必要的 "!" 与 "好" 加了  在本例中也正常了
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: 你◆吗◆ 还行◆
    
      FreeAndNil(reg);
    end;
    { 本来是有一个选项 [preExtra] 禁止乱用的, 但效果不好}
    
    
    正则表达式中的特殊字符表:
    特殊字符  在正则表达式中的意义  匹配字符本身  
    ^ 匹配字符串的开始,或不匹配 [] 中的内容 ^ 
    $ 匹配字符串的结尾 $ 
    ( 和 ) 标记子表达式 ( 和 ) 
    [ 和 ] 匹配"多种字符" 的表达式 [ 和 ] 
    { 和 } 匹配次数的符号 { 和 } 
    . 匹配除换行符以外的所有字符 . 
    ? 匹配 0 次或 1 次 ? 
    + 匹配至少 1 次 + 
    * 匹配 0 次或任意次 * 
    | 或 | 
     转义符号本身 \ 
    
    
    //准备: 我们先写一个搜索所有英文单词的表达式
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'one two three four five six seven eight nine ten';
      reg.RegEx   := '[A-Za-z]+'; //这个表达式就可以找到所有的英文单词
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆
    
      FreeAndNil(reg);
    end;
    
    
    //假如我们只需要每个单词的第一个字母呢? 这要用到子表达式
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'one two three four five six seven eight nine ten';
      reg.RegEx   := '([A-Za-z])[A-Za-z]*'; //注意表达式中有子表达式, 在 () 中
      reg.Replacement := '1'; // 1 引用了第一个子表达式
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: o t t f f s s e n t
    
      FreeAndNil(reg);
    end;
    
    
    //表达式中可以有多个子表达式
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'one two three ten';
      reg.RegEx   := '(t)(w+)';
      reg.Replacement := '[1-2:]'; // 12 分别引用对应的子表达式;  引用整个表达式
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: one [t-wo:two] [t-hree:three] [t-en:ten]
    
      FreeAndNil(reg);
    end;
    
    
    //匹配右边
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi 6; Delphi 7; Delphi 2007; Delphi Net';
      reg.RegEx   := 'Delphi (?=2007)'; // ?=
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: Delphi 6; Delphi 7; ◆2007; Delphi Net
    
      FreeAndNil(reg);
    end;
    
    
    //不匹配右边
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi 6; Delphi 7; Delphi 2007; Delphi Net';
      reg.RegEx   := 'Delphi (?!2007)'; // ?!
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆6; ◆7; Delphi 2007; ◆Net
    
      FreeAndNil(reg);
    end;
    
    
    //匹配左边
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '111, 222, ¥333, ¥444';
      reg.RegEx   := '(?<=¥)d{3}'; // ?<=
      reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: 111, 222, ¥◆, ¥◆
    
      FreeAndNil(reg);
    end;
    
    
    //不匹配左边
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '111, 222, ¥333, ¥444';
      reg.RegEx   := '(?  reg.Replacement := '◆';
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆, ◆, ¥333, ¥444
      FreeAndNil(reg);
    end;
    
    
    // preCaseLess: 不区分大小写, 相当于其他语言中的 i
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'abc ABC aBc';
      reg.RegEx   := 'abc';
      reg.Replacement := '◆';
    
      reg.Options := [preCaseLess]; //选项是集合类型的
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆ ◆ ◆
    
      FreeAndNil(reg);
    end;
    
    
    // preAnchored: 只匹配字符串开始, 相当于 ^, 不过还是有区别的
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'abc abc abc';
      reg.RegEx   := 'abc';
      reg.Replacement := '◆';
    
      reg.Options := [preAnchored]; //指定: preAnchored
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆ abc abc
    
      FreeAndNil(reg);
    end;
    {preAnchored 选项和 ^ 的区别:
      1、任何情况下, preAnchored 只匹配字符串开头;
      2、在 preMultiLine 选项模式下, ^ 还能匹配每行的开头;
      3、^ 还有其他用途.
    }
    
    
    // preDollarEndOnly: 让 $ 只匹配字符串结尾
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'abc abc abc'#13#10 +
                     'abc abc abc'#13#10 +
                     'abc abc abc';
      reg.RegEx   := 'abc$';  //当然需要有 $
      reg.Replacement := '◆';
    
      reg.Options := [preDollarEndOnly]; //指定: preDollarEndOnly
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject);
    {返回:
      abc abc abc
      abc abc abc
      abc abc ◆
    }
    
      FreeAndNil(reg);
    end;
    
    
    // preMultiLine: 多行匹配, 相当于其他语言中的 m
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'abc abc abc'#13#10 +
                     'abc abc abc'#13#10 +
                     'abc abc abc';
      reg.RegEx   := '^abc';
      reg.Replacement := '◆';
    
      reg.Options := [preMultiLine]; //指定: preMultiLine
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject);
    {返回:
      ◆ abc abc
      ◆ abc abc
      ◆ abc abc
    }
    {如果不指定 preMultiLine 将返回:
      ◆ abc abc
      abc abc abc
      abc abc abc
    }
    
      FreeAndNil(reg);
    end;
    {
      1、preMultiLine 是对 ^ 和 $ 的扩展使用;
      2、在指定了 [preAnchored] 或 [preDollarEndOnly] 的情况下无效.
    }
    
    
    // preSingleLine: 让特殊符号 . 能够匹配换行符 (. 的本意是匹配换行符以外的任意字符)
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'aaa;bbb;'#13#10 +
                     '111;222;'#13#10 +
                     'AAA;BBB;';
      reg.RegEx   := ';.';
      reg.Replacement := '◆';
    
      reg.Options := [preSingleLine]; //指定: preSingleLine
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject);
    {返回:
      aaa◆bb◆
      111◆22◆
      AAA◆BB;
    }
    {如果不指定 preMultiLine 将返回:
      aaa◆bb;
      111◆22;
      AAA◆BB;
    }
    
      FreeAndNil(reg);
    end;
    
    
    // preUnGreedy: 指定为非贪婪模式
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := '《Delphi》and《C++Builder》';
      reg.RegEx   := '《.*》';
    
      reg.Replacement := '◆';
    
      reg.Options := [preUnGreedy]; //指定: preUnGreedy
      { 在本例中, reg.RegEx := '《.*?》'; 可以达到同样的效果}
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: ◆and◆ ; 如果不指定 preUnGreedy, 将返回: ◆
    
      FreeAndNil(reg);
    end;
    
    
    // preExtended: 指定为扩展模式
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'Delphi C++Builder';
      reg.RegEx   := 'ix20C'; // x20 是用十六进制的方式表示的空格
    
      reg.Replacement := '◆';
    
      reg.Options := [preExtended]; //指定: preExtended
    
      reg.ReplaceAll;
    
      ShowMessage(reg.Subject); //返回: Delph◆++Builder
    
      FreeAndNil(reg);
    end;
    {preExtended 是最复杂的一个选项:
      1、它会忽略表达式中的空白, 譬如: 本例中的表达式如果是 'i C' 将不会匹配成功;
      2、空白要用相应的十六进制表示, 譬如用 x20 表示空格;
      3、把表达式中从 # 到行尾的部分当作注释而被忽略;
      4、如果要使用 # ,需要用 # 代替;
      5、表达式的标准注释是: (?#...) 及其中 # 后面的内容均为注释, 不管指定 preExtended 与否
    }
    
    关于选项 preExtra:
    
    如果表达式中需要特殊字符 ^ $ ( ) [ ] { } . ? + * |  时, 需要加转义符号  ;
    默认状态下, 其他字符前面添加了  会识别为字符本身;
    preExtra 选项应该就是禁止这种情况的, 也就是不要在非特殊字符前加  ;
    但测试效果 ... 也许是我没弄明白!
    
    
    还有三个状态选项: preNotBOL, preNotEOL, preNotEmpty
    
    reg.State := [preNotBOL] 是让标记开始的 ^ 无效;
    reg.State := [preNotEOL] 是让标记结尾的 $ 无效;
    reg.State := [preNotEmpty] 没弄明白!
    
    
    另外这些选择是可以组合使用的, 譬如:
    
    reg.Options := [preCaseLess, preMultiLine, preSingleLine];
    reg.State := [preNotBOL, preNotEOL];
    
    
    //查找是否存在
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'd';
    
      if reg.Match then
        ShowMessage('找到了')
      else
        ShowMessage('没找到');
    
    
      FreeAndNil(reg);
    end;
    
    
    //查找是否存在(方法2)
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'd';
    
      reg.Match; //执行查找
    
      if reg.FoundMatch then  //布尔变量 FoundMatch 会告诉我们查找有没有结果
        ShowMessage('找到了')
      else
        ShowMessage('没找到');
    
    
      FreeAndNil(reg);
    end;
    
    
    //显示找到的第一个
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'd';
    
      if reg.Match then
        ShowMessage(reg.MatchedExpression)  //2
      else
        ShowMessage('没找到');
    
    
      FreeAndNil(reg);
    end;
    
    
    //分别显示找到的每一个和总数
    var
      reg: TPerlRegEx;
      num: Integer; //用 num 来计数
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'd';
    
      num := 0;
      while reg.MatchAgain do  //MatchAgain 是下一个
      begin
        ShowMessage(reg.MatchedExpression); //将分别显示: 2 0 0 7 3 2
        Inc(num);
      end;
        ShowMessage(IntToStr(num)); //6
    
      FreeAndNil(reg);
    end;
    
    
    //分别显示找到的每一个和总数(另一种写法)
    var
      reg: TPerlRegEx;
      num: Integer; //用 num 来计数
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'd';
    
      num := 0;
      if reg.Match then
      begin
        repeat
          ShowMessage(reg.MatchedExpression); //将分别显示: 2 0 0 7 3 2
          Inc(num);
        until (not reg.MatchAgain);
      end;
        ShowMessage(IntToStr(num)); //6
    
      FreeAndNil(reg);
    end;
    
    
    //目标字符串的位置与长度
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007 for Win32';
      reg.RegEx   := 'Delphi';
    
      while reg.MatchAgain do  //很明显: 本例只能找到一个结果
      begin
        ShowMessage(reg.MatchedExpression); //找到的字符串: Delphi
        ShowMessage(IntToStr(reg.MatchedExpressionOffset)); //它所在的位置: 10
        ShowMessage(IntToStr(reg.MatchedExpressionLength)); //它的长度: 6
      end;
    
      FreeAndNil(reg);
    end;
    
    
    // MatchedExpression 与 SubExpressions[0]
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'CodeGear Delphi 2007';
      reg.RegEx   := 'Delphi';
    
      while reg.MatchAgain do
      begin
        ShowMessage(reg.MatchedExpression); //Delphi; 这是匹配到的内容
        ShowMessage(reg.SubExpressions[0]); //Delphi; 也可以这样显示匹配到的内容
      end;
    {
      SubExpressions 是一个数组:
      SubExpressions[1] 储存第 1 个表达式匹配的内容;
      SubExpressions[2] 储存第 2 个表达式匹配的内容;
      SubExpressions[n] 储存第 n 个表达式匹配的内容;
    
      SubExpressions[0] 储存整个表达式匹配的内容;
    
      MatchedExpression 表示的不过是 SubExpressions[0].
    }
    
      FreeAndNil(reg);
    end;
    
    
    //提取子表达式匹配到的内容
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'abc A1111 BB222 CCC33 DDDD4';
      reg.RegEx   := '([A-D]+)([1-4]+)'; //这个表达式有两个子表达式构成
    
      while reg.MatchAgain do
      begin
        ShowMessage(reg.SubExpressions[0]); //将分别显示: A1111 BB222 CCC33 DDDD4
        ShowMessage(reg.SubExpressions[1]); //将分别显示: A BB CCC DDDD
        ShowMessage(reg.SubExpressions[2]); //将分别显示: 1111 222 33 4
    
        {另外:
          reg.SubExpressionCount      是子表达式的个数;
          reg.SubExpressionLengths[n] 是第 n 个表达式返回的字符串的长度;
          reg.SubExpressionOffsets[n] 是第 n 个表达式返回的字符串在源字符串中的位置
        }
      end;
    
      FreeAndNil(reg);
    end;
    
    
    //子表达式不能超过 MAX_SUBEXPRESSIONS = 99 个, MAX_SUBEXPRESSIONS 是 TPerlRegEx 的内置常数.
    
    
    
    //设定搜索范围: Start、Stop
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.Subject := 'ababab';
      reg.RegEx   := 'ab';
      reg.Replacement := '◆';
    
      reg.Start := 1;
      reg.Stop := 2;
      while reg.MatchAgain do
      begin
        reg.Replace;
      end;
      ShowMessage(reg.Subject); //返回: ◆abab
    
    
      reg.Subject := 'ababab';
      reg.Start := 3;
      reg.Stop := 4;
      while reg.MatchAgain do
      begin
        reg.Replace;
      end;
      ShowMessage(reg.Subject); //返回: ab◆ab
    
    
      reg.Subject := 'ababab';
      reg.Start := 5;
      reg.Stop := 6;
      while reg.MatchAgain do
      begin
        reg.Replace;
      end;
      ShowMessage(reg.Subject); //返回: abab◆
    
      FreeAndNil(reg);
    end;
    
    
    // Replace
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.RegEx   := 'ab';
      reg.Replacement := '◆';
    
      reg.Subject := 'ababab';
      reg.ReplaceAll;
      ShowMessage(reg.Subject); //返回: ◆◆◆
    
    
      reg.Subject := 'ababab';
      //下面四行程序, 相当于 reg.ReplaceAll;
      while reg.MatchAgain do
      begin
        reg.Replace;
      end;
    
      ShowMessage(reg.Subject); //返回: ◆◆◆
    
      FreeAndNil(reg);
    end;
    {
      ReplaceAll 函数返回的是 Boolean;
      Replace 函数返回的是 Replacement 的值, 当然是不能赋值的, 它仅仅是返回值.
    }
    
    
    // Compile、Study
    var
      reg: TPerlRegEx;
    begin
      reg := TPerlRegEx.Create(nil);
    
      reg.RegEx   := 'ab';
      reg.Options := [preCaseLess];
      reg.Compile; {编译表达式}
      reg.Study; {Study 方法会检查是否编译, 如果没有编译则执行 Compile}
    
      reg.Replacement := '◆';
      reg.Subject := 'abAbaB';
    
      reg.ReplaceAll;
      ShowMessage(reg.Subject); {返回: ◆◆◆}
    
      FreeAndNil(reg);
    end;
    
    {
      编译表达式, 会加快执行速度、降低启动速度;
      如果表达式比较复杂而又多次执行, 应该先编译;
      编译内容包括表达式选项.
    }
    
    
    // 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;
    
    
    
    //字符串分割: 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;
    
  • 相关阅读:
    【Elasticsearch 技术分享】—— ES 常用名词及结构
    【Elasticsearch 技术分享】—— Elasticsearch ?倒排索引?这都是什么?
    除了读写锁,JUC 下面还有个 StampedLock!还不过来了解一下么?
    小伙伴想写个 IDEA 插件么?这些 API 了解一下!
    部署Microsoft.ReportViewe
    关于TFS强制undo他人check out
    几段查看数据库表占用硬盘空间的tsql
    How to perform validation on sumbit only
    TFS 2012 Disable Multiple Check-out
    在Chrome Console中加载jQuery
  • 原文地址:https://www.cnblogs.com/lonsine/p/3971880.html
Copyright © 2011-2022 走看看