先核來源與已訂規則
本例每筆 JSON 後用 LF 分隔,但已抽出的備註 A、CRLF、B 要照留。全局把 CRLF 換 LF,即使 JSON 可讀,也已改欄內內容。
| 紀錄 | 輸入 JSON |
|---|---|
| 原例輸入 | {"memo":"A\r\nB"} |
比較兩條實際路徑
JSON.stringify 會把欄內原換行轉義,再於記錄後加 LF,就分開內容與分隔。更正備註仍 A B。
| 路徑 | 輸出 JSON |
|---|---|
| 錯誤路徑 | {"memo":"A\nB","exportRecord":"{\"memo\":\"A\\nB\"}\n"} |
| 更正路徑 | {"memo":"A\r\nB","exportRecord":"{\"memo\":\"A\\r\\nB\"}\n"} |
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};
import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
const memo=corrected?i.memo:i.memo.replace(/\r\n/g,'\n');
const exportRecord=JSON.stringify({memo})+'\n';
return {memo,exportRecord};
};
const cases=[{"label":"misleading base","input":{"memo":"A\r\nB"},"expected":{"memo":"A\nB","exportRecord":"{\"memo\":\"A\\nB\"}\n"},"corrected":false},{"label":"corrected base","input":{"memo":"A\r\nB"},"expected":{"memo":"A\r\nB","exportRecord":"{\"memo\":\"A\\r\\nB\"}\n"},"corrected":true},{"label":"single-line field","input":{"memo":"AB"},"expected":{"memo":"AB","exportRecord":"{\"memo\":\"AB\"}\n"},"corrected":true},{"label":"empty memo field","input":{"memo":""},"expected":{"memo":"","exportRecord":"{\"memo\":\"\"}\n"},"corrected":true}];
for(const test of cases){
const actual=run(test.input,test.corrected);
assert.deepEqual(actual,test.expected,test.label);
console.log(test.label,actual);
}
下次載入前核邊界
單行及容許的空備註,來回都不新增換行內容。
| 情況 | 輸入 JSON | 預期輸出 JSON |
|---|---|---|
| 單行備註 | {"memo":"AB"} | {"memo":"AB","exportRecord":"{\"memo\":\"AB\"}\n"} |
| 容許的空備註 | {"memo":""} | {"memo":"","exportRecord":"{\"memo\":\"\"}\n"} |
匯出每筆用 LF,是否也要改備註 CRLF?
查看參考答案
不用,紀錄分隔與欄內容各有約定。備註照留,在 JSON 內轉義 CRLF。