mmday-firebase/src/kbo/html-utils.ts
윤정민 5888d446b7 Implement KBO game detail retrieval with dynamic caching and API.
- KBO 게임센터의 스코어보드, 박스스코어, 키플레이어 데이터를 통합 조회하는 기능을 구현했습니다.
- 경기 상태(종료, 진행 중, 시작 전)에 따라 TTL을 30초에서 7일까지 유연하게 적용하는 동적 캐싱 시스템을 도입했습니다.
- KBO 공식 데이터에서 이닝별 득점이 누락되는 경우를 대비해 네이버 스포츠 API를 통한 데이터 보완 로직을 추가했습니다.
- Firestore의 중첩 배열 저장 제한을 회피하기 위해 테이블 데이터를 객체 배열 구조로 파싱하도록 설계했습니다.
- CLI 상세 조회 명령어와 REST API 엔드포인트를 추가하고, HTML 엔티티 디코딩 및 관련 단위 테스트를 보완했습니다.
2026-04-30 16:34:09 +09:00

31 lines
947 B
TypeScript

export function extractHiddenField(html: string, name: string): string {
const re = new RegExp(`id="${name}"[^>]*value="([^"]*)"`, "i");
const match = html.match(re);
if (match) return match[1];
const re2 = new RegExp(`name="${name}"[^>]*value="([^"]*)"`, "i");
const match2 = html.match(re2);
return match2?.[1] ?? "";
}
export function stripTags(html: string): string {
return html.replace(/<[^>]*>/g, "").trim();
}
export function decodeHtmlEntities(text: string): string {
return text
.replace(/&nbsp;/g, " ")
.replace(/&amp;/g, "&")
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&quot;/g, "\"")
.replace(/&#(\d+);/g, (_, n) => String.fromCharCode(Number(n)));
}
export function padCell(val: string, w: number): string {
const displayWidth = [...val].reduce(
(sum, ch) => sum + (ch.charCodeAt(0) > 0x7f ? 2 : 1),
0
);
return val + " ".repeat(Math.max(0, w - displayWidth));
}