在 Delphi 中使用 System.RegularExpressions.TRegEx.Split 進行字串分割時,正則運算式中的「捕獲群組」會顯著改變回傳陣列的內容。本文透過實例說明不同群組寫法對分割結果的具體影響,幫助開發者避開常見陷阱。
const FSourceText = '1: AAA 2: BBB 3: CCC';
// 分隔符模式:一個數字 + 冒號 + 空格
\d: Arr := TRegEx.Split(FSourceText, '\d: ');
// 結果:['AAA', 'BBB', 'CCC']
標準分割,分隔符本身不會出現在結果中。
(\d): Arr := TRegEx.Split(FSourceText, '(\d): ');
// 結果:['', '1', 'AAA', '2', 'BBB', '3', 'CCC']
捕獲群組的內容會被當作獨立元素插入結果陣列中,導致結果包含分隔符中的數字。
(\d:) Arr := TRegEx.Split(FSourceText, '(\d:) ');
// 結果:['', '1:', 'AAA', '2:', 'BBB', '3:', 'CCC']
群組擴大時,整個 1:、2: 等字串會成為結果元素。
(\d)(:) Arr := TRegEx.Split(FSourceText, '(\d)(:) ');
// 結果:['', '1', ':', 'AAA', '2', ':', 'BBB', '3', ':', 'CCC']
多個捕獲群組時,所有群組內容皆會依序插入結果,此處只有第二個群組 : 可見,第一個群組數字同樣被插入。
(\d)(:)( )Arr := TRegEx.Split(FSourceText, '(\d)(:)( )');
// 結果:['', '1', ':', ' ', 'AAA', '2', ':', ' ', 'BBB', '3', ':', ' ', 'CCC']
三個群組內容(數字、冒號、空格)全部分別成為陣列元素。
(?:...) 或避免使用括號。// 僅分割,不保留分隔符細節
Arr := TRegEx.Split(FSourceText, '(?:\d): ');
// 或直接
Arr := TRegEx.Split(FSourceText, '\d: ');
理解此行為差異,能在解析結構化文字(如日誌、CSV 變體)時精確控制輸出格式,避免後續處理邏輯出錯。