zoukankan      html  css  js  c++  java
  • TPerlRegEx正则式控件入门

    //在后面介绍 TPerlRegEx 类的方法时, 关于对 (子表达式) 的引用还有更多话题.

    Delphi 正则表达式语法(9): 临界匹配 - 也叫"预搜索"与"反向预搜索"
    //匹配右边
    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   := '(?<!¥)/d{3}'; // ?<!
    reg.Replacement := '◆';
    reg.ReplaceAll;

    ShowMessage(reg.Subject); //返回: ◆, ◆, ¥333, ¥444
    FreeAndNil(reg);
    end;

    Delphi 正则表达式语法(10): 选项
    // 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   := 'i/x20C'; // /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];

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(1): 查找
    //查找是否存在
    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); //找到的字符串: 2007
        ShowMessage(IntToStr(reg.MatchedExpressionOffset)); //它所在的位置: 10
        ShowMessage(IntToStr(reg.MatchedExpressionLength)); //它的长度: 6
    end;

    FreeAndNil(reg);
    end;

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(2): 关于子表达式
    // 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   := '/b([A-D]+)([1-4]+)/b'; //这个表达式有两个子表达式构成

    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 的内置常数.

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(3): Start、Stop
    //设定搜索范围: 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;

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(4): Replace
    // 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 的值, 当然是不能赋值的, 它仅仅是返回值.
    }

    Delphi 正则表达式之TPerlRegEx 类的属性与方法(5): Compile、Study
    // 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;

    {
    编译表达式, 会加快执行速度、降低启动速度;
    如果表达式比较复杂而又多次执行, 应该先编译;
    编译内容包括表达式选项.
    }

    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;

  • 相关阅读:
    微软紧急安全公告:当心SQL攻击爆发
    婴儿
    感冒了
    System.IO.FileAttributes
    mssql数据库,无法用语句实现“强制还原”功能
    好大的风
    无聊的游戏
    JZOJ 4276【NOIP2015模拟10.28A组】递推
    JZOJ 4289.Mancity
    单词检索(search)
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940601.html
Copyright © 2011-2022 走看看