假如有这样一串文本: 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> // 指定名称的子子表达式; 当前版本不支持
上面这些不是全部, 但已是主要脉络; 其他内容也都是围绕这个思路.