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> // 指定名称的子子表达式; 当前版本不支持


 
   

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

你可能感兴趣的:(express)