Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 66x 66x 66x 66x 66x 66x 66x 22604x 22604x 43x 6x 2x 2x 4x 4x 37x 37x 22561x 4x 4x 22557x 2352x 2352x 2352x 20205x 1x 1x 1x 1x 1x 1x 20204x 1143x 1143x 1143x 1143x 1143x 19061x 19061x 66x 64x 64x 66x 59x 200x 58x 200x 2x 2x 2x 198x 30x 3x 27x 7x 7x 7x 8x 7x 57x 56x 56x 56x | /**
* 高性能 CSV 解析器/序列化器
* 支持 RFC 4180 标准:引号转义、字段内换行、逗号处理
*/
export function parseCsv(text: string): string[][] {
const rows: string[][] = [];
const len = text.length;
let i = 0;
let row: string[] = [];
let field = '';
let inQuotes = false;
while (i < len) {
const ch = text[i];
if (inQuotes) {
if (ch === '"') {
if (i + 1 < len && text[i + 1] === '"') {
field += '"';
i += 2;
} else {
inQuotes = false;
i++;
}
} else {
field += ch;
i++;
}
} else {
if (ch === '"') {
inQuotes = true;
i++;
} else if (ch === ',') {
row.push(field);
field = '';
i++;
} else if (ch === '\r') {
row.push(field);
field = '';
rows.push(row);
row = [];
i++;
Eif (i < len && text[i] === '\n') i++;
} else if (ch === '\n') {
row.push(field);
field = '';
rows.push(row);
row = [];
i++;
} else {
field += ch;
i++;
}
}
}
if (field || row.length > 0) {
row.push(field);
rows.push(row);
}
return rows;
}
export function normalizeRows(rows: string[][]): string[][] {
if (rows.length === 0) return rows;
const maxCols = Math.max(...rows.map(r => r.length));
return rows.map(r => {
if (r.length < maxCols) {
const padded = [...r];
while (padded.length < maxCols) padded.push('');
return padded;
}
return r;
});
}
function escapeField(field: string): string {
if (field.includes(',') || field.includes('"') || field.includes('\n') || field.includes('\r')) {
return '"' + field.replace(/"/g, '""') + '"';
}
return field;
}
export function serializeCsv(headers: string[], rows: string[][]): string {
const lines: string[] = [];
lines.push(headers.map(escapeField).join(','));
for (const row of rows) {
lines.push(row.map(escapeField).join(','));
}
return lines.join('\n');
}
export interface ParsedCsv {
headers: string[];
rows: string[][];
}
export function parseAndSplit(text: string): ParsedCsv {
if (!text.trim()) return { headers: [], rows: [] };
const allRows = normalizeRows(parseCsv(text));
Iif (allRows.length === 0) return { headers: [], rows: [] };
return { headers: allRows[0], rows: allRows.slice(1) };
}
|