假如有這樣一串文本: 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[0] 放置第一個子表達式的匹配結果 }
n := Match.Groups[2].Value; { Groups[0] 放置第二個子表達式的匹配結果 }
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> // 指定名稱的子子表達式; 當前版本不支持
上面這些不是全部, 但已是主要脈絡; 其他內容也都是圍繞這個思路.