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