当前位置: 首页 > news >正文

【RN】实现markdown文本简单解析

需求

  • 支持文本插入,比如 xxx {product_name} xxx ,如果提供了product_name变量的值为feedback,则可以渲染出 xxx feedback xxx
  • 支持链接解析,比如 [baidu](https://www.baidu.com/),可以直接渲染成超链接的形式。
  • 支持插入reactnode元素,比如 xxx {jump_node} xxx,且jump_node是一个reactnode元素,则可以将node节点插入到{}位置上。

实现

步骤:

  • 先解析链接, 返回这样子的数据结构。超链接返回url-text的对象,非超链接直接返回文本字符串
export interface LinkPart {text: string;url?: string;onClick?: string;
}export type ParsedTextPart = string | LinkPart;[{text: 'baidu',url: 'https://www.baidu.com/',},'other content','other content',
];
  • 遍历解析后的超链接数组,如果是对象,则渲染超链接;如果是字符串,继续解析
  • 解析字符串,判断需要解析的{}里面的文本是否是纯文本,如果是纯文本,则直接Text渲染;如果是react元素,则渲染该元素

TextTemplate.tsx:

import React, { ReactNode } from 'react';
import { routeCenter } from '@shopeepay-rn/route-center';
import { usePageContainerContext } from '@shopeepay-rn/page-container';
import { StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native';
import { parseLinkText } from '../../utils';
import styles from './styles';interface Props {template: string;// eg: {product_name:'spp', click_node:<Text></Text>}replaceValueMap: Record<string, string | number | ReactNode>;textStyle?: StyleProp<TextStyle>;containerStyle?: StyleProp<ViewStyle>;
}/*** 支持解析字符串、解析react元素、解析超链接* @param template 需要解析的字符串* @param replaceValueMap 需要替换的key-value,value支持字符串和react元素* @param textStyle 字体样式* @param containerStyle 容器样式* @returns react元素*/
export const TextTemplate = ({template,replaceValueMap,textStyle,containerStyle,
}: Props) => {const { rootTag } = usePageContainerContext();const parseText = (text: string, index: number) => {const result: React.ReactNode[] = [];let lastIndex = 0;text.replace(/{(\w+)}/g, (match: string, key: string, offset: number) => {const replaceValue = replaceValueMap[key];if (offset > lastIndex) {// 未被匹配到的result.push(<Text key={index} style={textStyle}>{text.substring(lastIndex, offset)}</Text>);}if (React.isValidElement(replaceValue)) {// 需要替换的是reactnode元素result.push(React.cloneElement(replaceValue, { key: index }));} else if (typeof replaceValue === 'string') {// 需要替换的是字符串result.push(<Text key={index} style={textStyle}>{replaceValue}</Text>);}lastIndex = offset + match.length;return '';});if (lastIndex < text.length) {result.push(<Text key={index} style={textStyle}>{text.substring(lastIndex)}</Text>);}return result;};const parseTemplate = (text: string) => {// 解析链接const linkTexts = parseLinkText(text);return linkTexts?.map((part, index) => {return typeof part === 'string' ? (// 对于字符串,需要解析 纯字符串 还是 reactnode元素parseText(part, index)) : (<Textkey={index}style={styles.link}onPress={() =>routeCenter.navigateWeb(part.url || '',{navbar: {title: part.text || '',},},rootTag)}>{part.text}</Text>);});};return (<View style={[styles.textView, containerStyle]}><Text>{parseTemplate(template)}</Text></View>);
};

parseLinkText.ts:

export interface LinkPart {text: string;url?: string;onClick?: string;
}export type ParsedTextPart = string | LinkPart;const parseLinkText = (text: string): ParsedTextPart[] => {const regex = /\[([^\]]+)\]\(([^)]+)\)/g;const parts: ParsedTextPart[] = [];let lastIndex = 0;text.replace(regex,(match: string, p1: string, p2: string, offset: number) => {if (offset > lastIndex) {parts.push(text.substring(lastIndex, offset));}parts.push({ text: p1, url: p2 });lastIndex = offset + match.length;return '';});if (lastIndex < text.length) {parts.push(text.substring(lastIndex));}return parts;
};// FIXME: 添加 unit test
export { parseLinkText };

使用

<TextTemplatetemplate={"you can test the TextTemplate component, parse {string_text}, parse [baidu](https://www.baidu.com/) link, parse {click_node} to show popup"}replaceValueMap={{string_text:"test string",click_node:<Text>other react node</Text>}}textStyle={styles.titleText}
/>

相关文章:

【RN】实现markdown文本简单解析

需求 支持文本插入&#xff0c;比如 xxx {product_name} xxx &#xff0c;如果提供了product_name变量的值为feedback&#xff0c;则可以渲染出 xxx feedback xxx。支持链接解析&#xff0c;比如 [baidu](https://www.baidu.com/)&#xff0c;可以直接渲染成超链接的形式。支持…...

webpack plugin

webpack plugin webpack完成的复杂炫酷的功能依赖于插件机制&#xff0c;webpack的插件机制依赖于核心的库&#xff0c; tapable tapable是一个类似于nodejs的eventEmitter的库&#xff0c; 主要是控制钩子函数的发布喝定于&#xff0c;当时&#xff0c;tapable提供您的hook机…...

【busybox记录】【shell指令】date

目录 内容来源&#xff1a; 【GUN】【date】指令介绍 【busybox】【date】指令介绍 【linux】【date】指令介绍 使用示例&#xff1a; 打印前天的日期: 打印三个月零一天后的日期: 打印当年圣诞节的年数: 打印当前的全月名称和月的日期: 要打印一个没有前导零的日期&…...

同态加密和SEAL库的介绍(八)性能

本篇会对比三种加密方案&#xff0c;同时每种方案配置三种参数。即九种情况下的各个操作的性能差异&#xff0c;为大家选择合适的方案和合适的参数提供参考。表格中所有时长的单位均为微妙&#xff0c;即 。 当然数据量比较大&#xff0c;为了方便大家查找&#xff0c…...

华为OD-D卷数的分解

给定一个正整数n&#xff0c;如果能够分解为m(m > 1)个连续正整数之和&#xff0c;请输出所有分解中&#xff0c;m最小的分解。 如果给定整数无法分解为连续正整数&#xff0c;则输出字符串"N"。 输入描述: 输入数据为一整数&#xff0c;范围为&#xff08;1, 2^3…...

rk3588 low_delay_net_display注意事项

low_delay_net_display例子默认只支持YUV420和RGB888,如果需要支持YUV422&#xff0c;请添加下面部分&#xff1a; rk3588_nvr/build/app/low_delay_net_display$ git diff v4l2HdmiRX.cpp diff --git a/app/low_delay_net_display/v4l2HdmiRX.cpp b/app/low_delay_net_displa…...

Spring Boot 快速入门样例【后端 3】

Spring Boot 入门&#xff1a;从零到一构建你的第一个应用 Spring Boot 作为一个流行的Java框架&#xff0c;以其“习惯优于配置”的理念极大地简化了Spring应用的开发和部署过程。本文将带你一步步创建一个简单的Spring Boot应用&#xff0c;从环境准备到项目创建&#xff0c;…...

Linux云计算 |【第二阶段】NETWORK-DAY2

主要内容&#xff1a; VLAN技术、TRUNK模式、链路聚合、路由器 一、VLAN技术应用 广播域指接受同样广播消息的节点的集合&#xff0c;如在该集合中的任何一个节点传输一个广播帧&#xff0c;则所有其它能收到这个帧的节点都被认为是该广播帧的一部分&#xff1b; 交换机的所有…...

Java面试题(基础篇)③

目录 一&#xff0c; 与 equals 的区别&#xff1f; 二&#xff0c;接口和抽象类的区别&#xff1f; 三&#xff0c;请说出几个常见的异常&#xff1f; 四&#xff0c;请问你对Java 反射有了解吗&#xff1f; 五&#xff0c;浅拷贝和深拷贝区别&#xff1f; 一&#xff0c…...

Qt动态调用 - QMetaObject::invokeMethod

QMetaObject::invokeMethod 动态调用是 Qt 的元对象系统的一项强大功能&#xff0c;它允许在运行时通过名称调用槽函数、信号和普通成员函数。 这种能力对于构建灵活和可扩展的应用程序非常有用&#xff0c;比如插件系统或脚本接口。 动态调用方法 Qt 提供了 QMetaObject::i…...

html+css+js网页设计 星享咖啡6个页面(带js) ui还原度90%

htmlcssjs网页设计 星享咖啡6个页面&#xff08;带js&#xff09; ui还原度90% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等…...

docker上传镜像至阿里云

1、安装wsl2 WSL2安装&#xff08;详细过程&#xff09; 2、安装docker Docker在Windows下的安装及使用 3、创建私人阿里云镜像库 如何创建私人阿里云镜像仓库&#xff1f;&#xff08;保姆级&#xff09; 4、如何删除容器 (1) 查找正在使用该图像的容器 docker ps -a --filte…...

POS刷卡开发源码之语音播报-CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构

一、终端语音提醒的好处 1. 增强信息传递的有效性&#xff1a;在人们忙碌或者注意力分散时&#xff0c;语音提醒能够直接穿透噪音和干扰&#xff0c;确保重要信息被准确接收。 2. 提高操作的便捷性&#xff1a;用户无需停下手中的工作去查看屏幕或阅读文字&#xff0c;直接通过…...

jupyter notebook魔法命令

%xmode 魔法命令来控制异常报告&#xff1a; 输入魔法命令&#xff1a;在 IPython 或 Jupyter Notebook 的一个新单元格中&#xff0c;输入以下命令之一来设置异常报告模式&#xff1a; 切换到 Plain 模式&#xff08;简洁输出&#xff09;&#xff1a; %xmode Plain切换回 Con…...

Mysql事件

1&#xff1a;查询全局事件开关是否启动 SHOW VARIABLES LIKE %sche%; 关闭状态&#xff01;&#xff01;&#xff01;去开启如果已开启忽略 set global event_scheduler ON; ojbk 2&#xff1a;创建事件 step1&#xff1a; 链接打开自己的数据库 step2&#xff1a; 找…...

Unity Console 窗口输出对齐

起因&#xff1a;做了个工具在console窗口罗列一些信息&#xff0c;基本结构是 [ 文件名 &#xff1a;行号 ]&#xff0c;因为文件&#xff0c;行号长度不一&#xff0c;想要做到如下效果。 初步尝试&#xff0c;用以下方法&#xff1a; string format "{0,-10} …...

leetcode198_打家劫舍

思路 动态规划 func rob(nums []int) int {if len(nums) < 2 {return nums[0]}// dp[i] 表示到第i家为止&#xff0c;小偷能够偷窃到的最高金额dp : make([]int, len(nums))dp[0] nums[0]dp[1] max(nums[0], nums[1])for i:2; i<len(nums); i {if nums[i] dp[i-2] &…...

C# 串口通讯怎么防止数据丢失

串口通信&#xff08;Serial Communication&#xff09;是计算机与设备之间进行数据交换的一种方式。在C#中进行串口通信时&#xff0c;防止数据丢失可以采取以下一些措施&#xff1a; 1.校验和&#xff08;Checksum&#xff09;&#xff1a;在发送数据时&#xff0c;计算数据的…...

【机器学习】BP神经网络中的链式法则:解开智能背后的数学奥秘

在浩瀚的机器学习领域中&#xff0c;BP&#xff08;反向传播&#xff09;神经网络如同一座桥梁&#xff0c;连接着复杂的数据世界与智能的彼岸。而这座桥梁的基石之一&#xff0c;便是链式法则&#xff08;Chain Rule&#xff09;——一个看似简单却蕴含无限智慧的数学原理。今…...

MyBatis 基本操作 - 注解版

目录 一&#xff0c;查询 - select 1.1 全列查询 1.2 指定列查询 1.3 赋值问题 方法一&#xff1a;起别名 方法二&#xff1a;结果映射 方法三&#xff1a;添加配置 二&#xff0c;新增 - Insert 2.1 使用对象插入 2.2 获取主键 三&#xff0c;删除 - Delete 四&am…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...