var result = Regex.Split("1,2,3,\"4,5,7,8\",6,\"7\"\"8\"",
@"(?<!""(\d+,)*\d+),(?!\d+(,\d+)*"")");
此正則使用零寬度斷言 (Lookaround) 實現「不分隔引號內的逗號」:
(?<!""(\d+,)*\d+) — 負向後顧斷言:確保逗號左側 不是 「雙引號 + 純數字欄位 (含內部逗號)」。(?!\d+(,\d+)*"") — 負向前顧斷言:確保逗號右側 不是 「純數字欄位 + 雙引號」。\d+,若欄位含字母 (如 "a,b,c") 即失效。\"7\"\"8\" 代表欄位值 7"8 (CSV 標準雙引號跳脫),此正則無法正確解析。參考同系列文章 (ID 36554) 的狀態機實作:normal / inquote 兩狀態,單趟掃描字元,遇引號切換狀態,逗號僅在 normal 狀態分割。可正確處理:
"" → ")public static IEnumerable ParseCsvLine(string line) {
var field = new StringBuilder();
bool inQuote = false;
for (int i = 0; i < line.Length; i++) {
char c = line[i];
if (c == '"') {
if (inQuote && i + 1 < line.Length && line[i+1] == '"') {
field.Append('"'); i++; // 跳脫雙引號
} else {
inQuote = !inQuote; // 進入/離開引號區塊
}
} else if (c == ',' && !inQuote) {
yield return field.ToString();
field.Clear();
} else {
field.Append(c);
}
}
yield return field.ToString(); // 最後一欄
}
正則雖短但脆弱,CSV 解析請務必用狀態機或成熟庫 (如 CsvHelper、TextFieldParser),避免邊界情況導致資料損壞。