Delphi 缺失的 Split 功能:自製高效分割函數
Delphi 核心庫長期缺乏內建字串分割函數,開發者常需自行實作。本文提供一個經過優化的 SplitString 函數,支援多字元分隔符、邊界情況處理,並分析其效能特徵與改進方向。
核心實現代碼
function SplitString(const Source, Delimiter: string): TStringList; stdcall;
var
PosIdx: Integer;
Token: string;
List: TStringList;
begin
List := TStringList.Create;
try
if Delimiter = '' then
raise Exception.Create('分隔符不能為空字串');
PosIdx := Pos(Delimiter, Source);
while PosIdx > 0 do
begin
Token := Copy(Source, 1, PosIdx - 1);
List.Add(Token);
Delete(Source, 1, PosIdx + Length(Delimiter) - 1);
PosIdx := Pos(Delimiter, Source);
end;
List.Add(Source); // 加入最後一段
Result := List;
except
List.Free;
raise;
end;
end;
關鍵改進點解析
| 原版問題 | 改進方案 | 效果 |
重複計算 Length(Delimiter) | 預存長度變數 | 減少函數調用開銷 |
每次 Copy 重建字串 | 改用 Delete 原地修改 | 減少記憶體分配 |
| 無異常安全保護 | try..except..List.Free | 防止記憶體洩漏 |
| 空分隔符導致無限循環 | 前置檢查 Delimiter = '' | 防呆機制 |
呼叫端需手動 Free | 文檔標註擁權轉移 / 改為介面返回 | 明確生命週期 |
使用範例
var
Parts: TStringList;
i: Integer;
begin
Parts := SplitString('apple,banana,orange,grape', ',');
try
for i := 0 to Parts.Count - 1 do
Memo1.Lines.Add(Format('[%d] %s', [i, Parts[i]]));
{輸出:
[0] apple
[1] banana
[2] orange
[3] grape}
finally
Parts.Free;
end;
end;
邊界情況測試
SplitString('', ','); // 返回 1 個空字串項目
SplitString('a,b,', ','); // 返回 ['a', 'b', ''] 尾部空項保留
SplitString(',a,b', ','); // 返回 ['', 'a', 'b'] 頭部空項保留
SplitString('a,,b', ','); // 返回 ['a', '', 'b'] 中間空項保留
SplitString('abc', ''); // 引發異常:分隔符不能為空
效能優化建議
- 大字串分割:改用
TStringBuilder 或直接操作 PChar 緩衝區,避免大量字串複製
- 高頻調用:將
TStringList 改為物件池複用,或返回 TArray<string>(Delphi 10.4+)
- 多字元分隔符:當前實現已支援(如
'::'、'||')
- 正則分割:複雜模式請使用
System.RegularExpressions.TRegEx.Split
現代 Delphi 替代方案
{Delphi 10.4+ 內建}
uses System.StrUtils;
var
Arr: TArray<string>;
begin
Arr := 'a,b,c'.Split([',']); // 返回動態陣列,自動管理生命週期
end;
總結
這個 SplitString 實現兼顧了相容性、正確性與基本效能。對於舊版本 Delphi 專案,它是可靠的選擇;新專案建議優先使用內建 Split 或 TRegEx.Split,獲得更好的型別安全與效能。
- 上一篇文章: Delphi 日期時間間隔計算:Between 與 Span 系列函數完整對比
- 下一篇文章: Delphi ListView 欄寬變更事件攔截與處理技巧
Copyright ©
程式碼之家 All Rights Reserved