Text组件如何渲染包含em标签的html字符串
========================

#### 问题现象

html字符串中包含em标签，使用Text组件如何增强对于文本的渲染？

#### 效果预览

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/97/v3/i75lXJMGTge-ISIz1YWVXA/zh-cn_image_0000002658791787.png?HW-CC-KV=V1&HW-CC-Date=20260709T133907Z&HW-CC-Expire=86400&HW-CC-Sign=D04D9AF12A01E1E2AAF8AAD5EA69705B2D277E3D4E7DE737C3F66E3BEB5AA059 "点击放大")

#### 背景知识

*   [ForEach](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-rendering-control-foreach)：接口基于数组类型数据来进行循环渲染。
*   [Span](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-span)：作为Text、ContainerSpan组件的子组件，用于显示行内文本的组件。

#### 解决方案

1.  创建方法heightLightWord，使用正则表达式对html字符串进行解析，返回包含content和light字段的数组。
2.  使用ForEach遍历数组，根据light字段设置文本的渲染样式。

interface isHeightLight {
  content: string,
  light: boolean
}

@Entry
@Component
struct IndexOfPage {
  value: string \= '<em\>第</em\>二届海南<em\>岛</em\>国际<em\>电</em\>影节开幕式';

  heightLightWord(word: string) {
   _ // 先将需要高亮的字符筛选出来，待会高亮_
    let str \= word;
    let result: string\[\] \= \[\];
    let index \= 0;
    while ((index \= str.indexOf("<em\>", index)) !== -1) {
      if (index \+ 4 < str.length) {
        result.push(str\[index \+ 4\]);
      }
      index += 4;
    }
 _   // 将字符之间的html格式全部去除_
    let rt: string \= this.value.replace('<p\></p\><p\></p\>', '\\n').replace('<p\>', '\\n').replace('\\n\\n', '\\n');
    rt \= rt.replace(/<br\\s\*\\/?\>/g, '\\n');
    rt \= rt.replace(/<\\/?p/gi, '\\n');
    rt \= rt.replace(/<\[^\>\]+\>/g,
      '');
  _  // 取'\>'反的集合\[^\>\]，+匹配集合元素一次或多次_
    rt \= rt.replace(/\>/g, '');
    if (this.value) {
      rt \= rt.trim();
    }
    const wordArr \= rt.split('');
    const indexArr: number\[\] \= \[\];
  _  // 获取所有符合条件的下标_
    result.forEach((item: string) \=\> {
      let index \= wordArr.indexOf(item);
      while (index !== -1) {
        indexArr.push(index);
        index \= wordArr.indexOf(item, index \+ 1);
      }
    });
    return wordArr.map((item: string, index: number): isHeightLight \=\> {
      if (indexArr.indexOf(index) !== -1) {
        return { content: item, light: true };
      } else {
        return { content: item, light: false };
      }
    });
  }

  build() {
    Column() {
      Text() {
        ForEach(this.heightLightWord(this.value), (item: isHeightLight) \=\> {
          Span(item.content)
            .fontColor(item.light ? Color.Blue : Color.Black)
            .fontWeight(item.light ? FontWeight.Bolder : FontWeight.Normal)
            .fontSize(item.light ? 20 : 14)
        })
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}