// 最终验证:从 Axure 页面 HTML 提取全部文本(解码 HHHH; 实体),按控件类型分组 import fs from 'node:fs'; const html = fs.readFileSync('e:/code/crm-backend-matt/.scratch/lanhu-latest/team-page.html', 'utf8'); // 解码 HTML 实体 const decode = (s) => s .replace(/([0-9A-Fa-f]+);/g, (_, h) => String.fromCodePoint(parseInt(h, 16))) .replace(/(\d+);/g, (_, d) => String.fromCodePoint(parseInt(d, 10))) .replace(/ /g, ' ').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); // 按 Axure 控件注释分组提取: 后跟
文本
const re = /\s*([\s\S]*?)<\/span><\/p>/g) || []) .map(p => decode(p.replace(/<\/?p>/g, '').replace(/<\/?span>/g, ''))) .join(' | '); } items.push({ id, name: decode(name), type: decode(type), text: text.trim() }); } console.log('总控件数:', items.length); console.log('有文本的控件:', items.filter(i => i.text).length); console.log('\n=== 全部有文本的控件(id | 类型 | 名称 | 文本)==='); for (const i of items) { if (i.text) console.log(`${i.id.padEnd(7)} ${i.type.padEnd(6)} ${i.name.slice(0, 12).padEnd(12)} ${i.text.slice(0, 70)}`); } console.log('\n=== 类型分布 ==='); const dist = {}; items.forEach(i => dist[i.type] = (dist[i.type] || 0) + 1); console.log(JSON.stringify(dist, null, 0));