diff --git a/src/matrix.test.ts b/src/matrix.test.ts index 53067339..ded9dc3a 100644 --- a/src/matrix.test.ts +++ b/src/matrix.test.ts @@ -65,6 +65,13 @@ describe("Matrix.split()", () => { expect(Matrix.split(CSV, Number)).toEqual(EXAMPLE_MATRIX); }); + const CSVWithTrailingNewline = `${CSV}\n`; + test("Constructs a matrix from a CSV string with trailing newline", () => { + expect(Matrix.split(CSVWithTrailingNewline, Number)).toEqual( + EXAMPLE_MATRIX + ); + }); + test("Keeps line breaks inside double quotes", () => { const csv = '"Value\n1"\tValue2\t"Value\n3"'; const result = Matrix.split(csv, (value) => value); diff --git a/src/matrix.ts b/src/matrix.ts index e275104f..b12230b5 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -167,18 +167,29 @@ export function split( horizontalSeparator = "\t", verticalSeparator: string | RegExp = /\r\n|\n|\r/ ): Matrix { + const verticalSeparatorRegExp = + typeof verticalSeparator === "string" + ? new RegExp(verticalSeparator) + : verticalSeparator; + // Temporarily replace line breaks inside quotes const replaced = csv.replace(/"([^"]*?)"/g, (match, p1) => { return p1.replace(/\n/g, "\\n"); }); - return replaced.split(verticalSeparator).map((row) => - row - .split(horizontalSeparator) - .map((line) => { - // Restore original line breaks in each line - return line.replace(/\\n/g, "\n"); - }) - .map(transform) + return ( + replaced + // delete trailing new line character + .replace(new RegExp(`(${verticalSeparatorRegExp.source})$`), "") + .split(verticalSeparatorRegExp) + .map((row) => + row + .split(horizontalSeparator) + .map((line) => { + // Restore original line breaks in each line + return line.replace(/\\n/g, "\n"); + }) + .map(transform) + ) ); }