백테스팅 분석결과 레포트 출력
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* 잘못된 인코딩으로 깨진 한글 문자열 복구 (레포트·전략명 등)
|
||||
* — UTF-8 바이트가 Latin-1 으로 해석된 경우(3ë ¶ → 3분, 1시간 → 1시간)
|
||||
*/
|
||||
|
||||
/** Latin-1 바이트 → UTF-8 재해석 */
|
||||
function repairFromLatin1Bytes(text: string): string | null {
|
||||
try {
|
||||
const bytes = Uint8Array.from(text, c => c.charCodeAt(0) & 0xff);
|
||||
const repaired = new TextDecoder('utf-8', { fatal: false }).decode(bytes);
|
||||
if (!repaired || repaired.includes('\uFFFD')) return null;
|
||||
if (/[\uAC00-\uD7A3]/.test(repaired)) return repaired;
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** DB·레거시에서 자주 보이는 깨진 패턴 */
|
||||
function repairKnownMojibakePatterns(text: string): string {
|
||||
let out = text;
|
||||
const rules: [RegExp, string][] = [
|
||||
[/CC\s+l(?=\s*[0-9])/gi, 'CCI'],
|
||||
[/1시간/gi, '1시간'],
|
||||
[/시간/gi, '시간'],
|
||||
[/([0-9]+)\s*ë\s*¶/gi, '$1분'],
|
||||
[/ë\s*¶/gi, '분'],
|
||||
[/시/gi, '시'],
|
||||
[/ê°„/gi, '간'],
|
||||
[/é/g, 'é'],
|
||||
[/Ã /g, ' '],
|
||||
];
|
||||
for (const [re, rep] of rules) {
|
||||
out = out.replace(re, rep);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function hasHangul(text: string): boolean {
|
||||
return /[\uAC00-\uD7A3]/.test(text);
|
||||
}
|
||||
|
||||
function hasMojibakeMarkers(text: string): boolean {
|
||||
return /[ìíîïðñòóôõö÷øùúûüÿàáâãäåæçèêë]/.test(text)
|
||||
|| /ë\s*¶/.test(text)
|
||||
|| /시/.test(text)
|
||||
|| /ê°„/.test(text)
|
||||
|| /Ã.|Â./.test(text);
|
||||
}
|
||||
|
||||
function looksLikeBrokenKorean(text: string): boolean {
|
||||
if (!text) return false;
|
||||
if (hasHangul(text) && hasMojibakeMarkers(text)) return true;
|
||||
if (hasMojibakeMarkers(text) && !hasHangul(text)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeReportText(text: string): string {
|
||||
return text
|
||||
.replace(/,{2,}/g, ', ')
|
||||
.replace(/\s*,\s*,+/g, ', ')
|
||||
.replace(/,\s*,/g, ', ')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 깨진 한글·시간봉 표기 복구. 이미 정상 UTF-8 이면 그대로 반환.
|
||||
*/
|
||||
export function repairUtf8Mojibake(text: string): string {
|
||||
if (!text) return text;
|
||||
|
||||
let result = text;
|
||||
|
||||
if (hasMojibakeMarkers(result)) {
|
||||
result = repairKnownMojibakePatterns(result);
|
||||
}
|
||||
|
||||
if (looksLikeBrokenKorean(text)) {
|
||||
const fromBytes = repairFromLatin1Bytes(text);
|
||||
if (fromBytes && hasHangul(fromBytes) && !looksLikeBrokenKorean(fromBytes)) {
|
||||
result = fromBytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMojibakeMarkers(result)) {
|
||||
result = repairKnownMojibakePatterns(result);
|
||||
}
|
||||
|
||||
return normalizeReportText(result);
|
||||
}
|
||||
Reference in New Issue
Block a user