You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML转JSON字符串时特殊上标字符显示异常问题求解

你的问题来自两个核心原因:

  • 你当前的解析逻辑只提取HTML片段的纯文本,丢失了<sup>标签的格式语义,同时原始内容里的Unicode上标字符ˢᵗ没有被兼容处理
  • 你项目使用的默认字体不支持ˢᵗ这类特殊Unicode字符,导致显示为方块乱码

解决思路

  1. 先完成HTML实体解码
    使用Dart官方html包的HtmlUnescape工具类,先把JSON中拿到的转义后的HTML字符(比如&lt;、&quot;)转回原始字符,不要直接用parseFragment的text属性丢弃格式:
import 'package:html/parser.dart';
import 'package:html/dom.dart';
import 'package:html_unescape/html_unescape.dart';

Achievement.fromJson(Map<String, dynamic> json) {
  final unescape = HtmlUnescape();
  // 先解码所有HTML实体
  String rawTitle = json['titel'] != null ? unescape.convert(json['titel']) : '';
  // 后续再处理上标内容
  titel = rawTitle;
}
  1. 处理上标显示,两种可选方案:
  • 方案1(推荐,保留上标样式):不要用原生Text组件,改用pub.dev上的flutter_html组件,直接渲染处理后的HTML内容,组件会自动识别<sup>标签渲染为上标,也会自动兼容特殊字符的显示,无需手动解析文本。
  • 方案2(使用原生Text组件):把所有特殊上标字符和HTML上标标签统一替换为普通文本,或者用Text.rich手动实现上标样式,规避特殊字符的字体兼容问题:
// 替换特殊字符示例
rawTitle = rawTitle.replaceAll('ˢᵗ', 'st').replaceAllMapped(RegExp(r'<sup>(.*?)<\/sup>'), (match) => match.group(1)!);

// 手动实现上标的Text.rich示例
Text.rich(
  TextSpan(
    children: [
      const TextSpan(text: 'Herosim in 21'),
      WidgetSpan(
        child: Transform.translate(
          offset: const Offset(0, -4),
          child: const Text('st', style: TextStyle(fontSize: 10)),
        ),
      ),
      const TextSpan(text: ' Century: The Example of "Dexter"'),
    ],
  ),
)
  1. 字体兜底兼容
    如果必须保留ˢᵗ这类特殊Unicode字符,给Text组件的style添加fontFamilyFallback属性,配置支持特殊字符的兜底字体,例如:
Text(
  titel,
  style: const TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w600,
    fontFamilyFallback: ['Noto Sans SC', 'Roboto'],
  ),
)

内容的提问来源于stack exchange,提问作者Jiho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 13:21:00