• RegularExpressions(3) RegularExpressions 的工作思路



    假如有这样一串文本: AAA1 BBB2 AA11 BB22 A111 B222 AAAA

    可以用表达式: [A-Za-z]+\d+ 提取到前六个字串. 测试代码:
    uses RegularExpressions;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Regex: IRegex; { RegularExpressions 提倡使用 IRegex 而不是 TRegex}
      Match: IMatch; { IMatch 表示匹配到的若干个字串中的一个 }
    begin
      { 构建表达式 }
      Regex := TRegex.Create('[A-Za-z]+\d+');
    
      { 下面就匹配出符合表达式的第一个字串 }
      Match := Regex.Match('AAA1 BBB2 AA11 BB22 A111 B222 AAAA');
      { 可用 Match.Value 获取匹配到的文本; 这里会是: AAA1 }
      { 可用 Match.Length 获取文本的长度; 这里会是: 4 }
      { 可用 Match.Index 获取字串在原串中的位置; 这里会是: 1, 第二个会是 6 }
    
      { 下面程序将遍历出所有匹配到的子串 }
      while Match.Success do       { IMatch.Success: 是否成功匹配 }
      begin
        ShowMessage(Match.Value);
        Match := Match.NextMatch;  { IMatch.NextMatch: 继续匹配下一个, 并返回下一个 IMatch 对象 }
      end;
    end;
    

    还是面对前面的文本: AAA1 BBB2 AA11 BB22 A111 B222 AAAA

    假如在之前匹配的基础上, 同时想提取其中的 "字母" 或 "数字", 就要用到子表达式;

    譬如, 表达式可以这样写: ([A-Za-z]+)(\d+)

    匹配到的子表达式会放置在 IMatch.Groups 中;
    Groups 是一个 IGroup 对象的集合, 它的元素总数 = 子表达式个数 + 1; 示例:
    uses RegularExpressions;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Regex: IRegex;
      Match: IMatch;
      s,w,n: string;
    begin
      Regex := TRegex.Create('([A-Za-z]+)(\d+)');
      Match := Regex.Match('AAA1 BBB2 AA11 BB22 A111 B222 AAAA');
    
      while Match.Success do
      begin
        s := Match.Groups[0].Value; { Groups[0] 放置整个表达式的匹配结果 }
        w := Match.Groups[1].Value; { Groups[1] 放置第一个子表达式的匹配结果 }
        n := Match.Groups[2].Value; { Groups[2] 放置第二个子表达式的匹配结果 }
        ShowMessageFmt('子串: %s; 字母: %s; 数字: %s', [s, w, n]);
        Match := Match.NextMatch;
      end;
    (*
    子串: AAA1; 字母: AAA; 数字: 1
    子串: BBB2; 字母: BBB; 数字: 2
    子串: AA11; 字母: AA; 数字: 11
    子串: BB22; 字母: BB; 数字: 22
    子串: A111; 字母: A; 数字: 111
    子串: B222; 字母: B; 数字: 222
    *)
    end;
    

    通过正则表达式主要就做两个工作: 查找、替换; 上面就是查找的基本思路, 再看替换, 直接是例子:
    uses RegularExpressions;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      Regex: IRegex;
      str: string;
    begin
      Regex := TRegex.Create('([A-Za-z]+)(\d+)');
    
      { 把表达式匹配到的文本替换为 ◆ }
      str := Regex.Replace('AAA1 BBB2 AA11 BB22 A111 B222 AAAA', '◆');
      ShowMessage(str); { ◆ ◆ ◆ ◆ ◆ ◆ AAAA }
    
      { 把表达式匹配到的文本替换为 "第一个子表达式的匹配结果" }
      str := Regex.Replace('AAA1 BBB2 AA11 BB22 A111 B222 AAAA', '$1');
      ShowMessage(str); { AAA BBB AA BB A B AAAA }
    
      { 把表达式匹配到的文本替换为 "第二个子表达式的匹配结果", 这里相当于删除数字 }
      str := Regex.Replace('AAA1 BBB2 AA11 BB22 A111 B222 AAAA', '$2');
      ShowMessage(str); { 1 2 11 22 111 222 AAAA }
    end;
    

    在替换中使用 $1 $2, 下面是所有类似引用的列表:
    $n      // 第几个子表达式, $0 表示整个表达式
    $&      // 同 $0
    $+      // 最后一个子表达式; 在上面例子中相当于 $2
    
    $_      // 替换整个输入字符串
    $`      // 替换匹配前的输入字符串的所有文本
    $'      // 替换匹配后的输入字符串的所有文本; 这在 Delphi 中得写作: $''
    
    $$      // 既然用 $ 做转义, 如果需要这个符号本身, 可以 $$
    
    $<name> // 指定名称的子子表达式; 当前版本不支持
    

    上面这些不是全部, 但已是主要脉络; 其他内容也都是围绕这个思路.

  • 相关阅读:
    如何勾选 servlet如何获取?
    过滤器 如何实现获取不到用户名跳转回登录界面
    验证码
    cookie保存用户名及密码
    游标
    存储过程和自定义函数的区别
    瞎搞
    sql 试图索引
    sql 常用函数
    sql 简单的定义变量 声明 输出
  • 原文地址:https://www.cnblogs.com/del/p/1640961.html
Copyright © 2020-2023  润新知