Java提取markdown中的表格
Java提取markdown中的表格
说明
这篇博文是一个舍近求远的操作,如果只需要要对markdown中的表格数据进行提取,完全可以通过正在表达式或者字符串切分来完成。但是鉴于学习的目的,这次采用了commonmark包中的工具来完成。具体实现过程如下
实现步骤
引入pom依赖
<dependency><groupId>org.commonmark</groupId><artifactId>commonmark</artifactId><version>0.21.0</version></dependency><dependency><groupId>org.commonmark</groupId><artifactId>commonmark-ext-gfm-tables</artifactId><version>0.21.0</version></dependency>
自定义vistor
import org.commonmark.ext.gfm.tables.*;
import org.commonmark.node.*;import java.util.ArrayList;
import java.util.List;public class TableVisitor extends AbstractVisitor {private boolean inHeader = false;private boolean inBody = false;private List<String> currentRow = null;private List<String> headers = new ArrayList<>();private final List<List<String>> rows = new ArrayList<>();@Overridepublic void visit(CustomBlock customBlock) {if (customBlock instanceof TableBlock) {handleTableBlock((TableBlock) customBlock);} else {super.visit(customBlock);}}@Overridepublic void visit(CustomNode customNode) {if (customNode instanceof TableHead) {handleTableHead((TableHead) customNode);} else if (customNode instanceof TableBody) {handleTableBody((TableBody) customNode);} else if (customNode instanceof TableRow) {handleTableRow((TableRow) customNode);} else if (customNode instanceof TableCell) {handleTableCell((TableCell) customNode);} else {super.visit(customNode);}}private void handleTableBlock(TableBlock tableBlock) {// 重置状态inHeader = false;inBody = false;visitChildren(tableBlock);}private void handleTableHead(TableHead tableHead) {inHeader = true;visitChildren(tableHead);inHeader = false;}private void handleTableBody(TableBody tableBody) {inBody = true;visitChildren(tableBody);inBody = false;}private void handleTableRow(TableRow tableRow) {currentRow = new ArrayList<>();visitChildren(tableRow);if (inHeader) {this.headers = currentRow;} else if (inBody) {this.rows.add(currentRow);}}private void handleTableCell(TableCell tableCell) {if (currentRow != null) {currentRow.add(getTextContent(tableCell));}visitChildren(tableCell);}private String getTextContent(Node node) {StringBuilder sb = new StringBuilder();Node child = node.getFirstChild();while (child != null) {if (child instanceof Text) {sb.append(((Text) child).getLiteral());}child = child.getNext();}return sb.toString().trim();}public List<String> getTableHeaders() {return headers;}public List<List<String>> getTableRows() {return rows;}
}
测试用例
public static void main(String[] args) {String content = """| 姓名 | 性别 | 班级 | 年龄 ||--------------|------|--------------------|--------------------|| 张三 | 男 | 兴趣一班 | 17 || 李四 | 男 | 兴趣一班 | 16 |""";List<Extension> extensions = Arrays.asList(TablesExtension.create());Parser parser = Parser.builder().extensions(extensions).build();Node document = parser.parse(content);TableVisitor visitor = new TableVisitor();document.accept(visitor);List<String> tableHeaders = visitor.getTableHeaders();List<List<String>> tableRows = visitor.getTableRows();System.out.println("表头: " + tableHeaders);System.out.println("表格行数据: "+ tableRows);}
总结
由于没有在commonmark中找到我们需要的vistor,所以自定义了vistor。希望可以对其他同学有所帮助吧。
相关文章:
Java提取markdown中的表格
Java提取markdown中的表格 说明 这篇博文是一个舍近求远的操作,如果只需要要对markdown中的表格数据进行提取,完全可以通过正在表达式或者字符串切分来完成。但是鉴于学习的目的,这次采用了commonmark包中的工具来完成。具体实现过程如下 实…...

立志成为一名优秀测试开发工程师(第七天)——unittest框架的学习
目录 unittest框架的学习 一、测试类的编写 创建相关测试类cal.py、CountTest.py 二、常见断言方法 使用unittest单元测试框架编写测试用例CountTest.py 注意:执行的时候光标一定要放在括号后面,鼠标右键运行 三、对测试环境的初始化和清除模块…...
精益数据分析(85/126):营收阶段的核心指标与盈利模型优化——从数据到商业决策的落地
精益数据分析(85/126):营收阶段的核心指标与盈利模型优化——从数据到商业决策的落地 c。 一、营收健康度的核心指标:投资回报率模型 (一)季度再发性营收增长率(QRR) 该指标衡量…...

论坛系统(4)
用户详情 获取用户信息 实现逻辑 ⽤⼾提交请求,服务器根据是否传⼊Id参数决定返回哪个⽤⼾的详情 1. 不传⽤⼾Id,返回当前登录⽤⼾的详情(从session获取) 2. 传⼊⽤⼾Id,返回指定Id的⽤⼾详情(根据用户id去查) 俩种方式获得用户信息 参…...
本地Markdown开源知识库选型指南
本地Markdown开源知识库选型指南 以下是几款优秀的本地Markdown开源知识库解决方案,适合不同需求场景: 1. Obsidian (非完全开源但免费) 特点:基于Markdown的本地优先知识管理,丰富的插件生态优势:双向链接、图形视…...
【.net core】SkiaSharp 如何在Linux上实现
1. 安装依赖库 首先需要安装 SkiaSharp 运行时依赖: # Ubuntu/Debian sudo apt-get update sudo apt-get install -y libfontconfig1 libfreetype6 libx11-6 libx11-xcb1 libxcb1 \libxcomposite1 libxcursor1 libxdamage1 libxi6 libxtst6 \libnss3 libcups2 lib…...
后端项目中静态文案国际化语言包构建选型
这是一个很关键的问题。在做国际化(i18n)时,不同语言包格式如 .resx、.properties 和 .json 都可用,但各自有适用场景、特性与限制,你在选择时可以根据你的开发语言、生态和维护成本权衡。 ✅ 一张对比表:.…...
前端面经 React常见的生命周期
初始化阶段 constructor state的初始化,防抖节流的绑定getDerivedStateFromProps 静态函数 当作纯函数使用 传入props和state,合并成一个新的statecomponentWillMount 组件如果有getDrivedStatefromprops不会执行 针对一些接口的预请求时使用rendercomp…...

力扣面试150题--二叉树的层平均值
Day 54 题目描述 思路 初次做法(笨):使用两个队列,一个队列存放树的节点,一个队列存放对应节点的高度,使用x存放上一个节点,highb存放上一个节点的高度,sum存放当前层的节点值之和…...

【Doris入门】Doris初识:分布式分析型数据库的核心价值与架构解析
目录 1 Doris简介与核心价值 2 Doris架构深度解析 2.1 Frontend(FE)架构 2.2 Backend(BE)架构 3 Doris核心概念详解 3.1 数据分布模型 3.2 Tablet与Replica 3.3 数据模型 4 Doris关键技术解析 4.1 存储引擎 4.2 查询执…...
C#面试问题41-60
41. What is the Singleton design pattern? Singleton is a class that only allows creating a single instance of itselt. 单例设计模式是一个类,它只允许创建自己的单个实例。 构造函数防止他在单例类以外的地方被调用。 使用情景:need a sing…...

数据结构与算法学习笔记(Acwing 提高课)----动态规划·区间DP
数据结构与算法学习笔记----动态规划区间DP author: 明月清了个风 first publish time: 2025.5.26 ps⭐️区间DP的特征在于子结构一般是一个子区间上的问题,涉及到的问题也非常多,如环形区间,记录方案数,高精度,二维…...
【合集】Linux——31个普通信号
Linux普通信号总表(1-31) 编号信号名触发原因默认动作1SIGHUP终端连接断开(如SSH会话终止)或守护进程重载配置(如nginx -s reload)终止进程2SIGINT用户输入CtrlC中断前台进程终止进程…...

从0到1搭建AI绘画模型:Stable Diffusion微调全流程避坑指南
从0到1搭建AI绘画模型:Stable Diffusion微调全流程避坑指南 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 从0到1搭建AI绘画模型:Stable Diffusion微调全流程避坑指南摘要引言一、数据集构…...
ASP.NET Core 中JWT的基本使用
文章目录 前言一、JWT与RBAC二、JWT 的作用三、RBAC 的核心思想四、使用1、配置文件 (appsettings.json)2、JWT配置模型 (Entity/JwtSettings.cs)3、服务扩展类,JWT配置 (Extensions/ServiceExtensions.cs)4、用户仓库接口服务5、认证服务 (Interface/IAuthService.…...
未来技术展望
应用场景:海量数据并行处理 技术融合: # 概念代码:量子加速的数据清洗 from quantum_processor import PhotonicProcessordef quantum_data_cleaning(data):# 使用光量子处理器并行处理千万级数据processor = PhotonicProcessor(model="Xanadu Borealis")return …...

从一到无穷大 #46:探讨时序数据库Deduplicate与Compaction的设计权衡
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 引言Compaction AlgorithmsCompact Execution Flow Based On VeloxLocalMergeSource的…...

vue3 导出excel
需求:导出自带格式的excel表格 1.自定义二维数组格式 导出 全部代码: <el-button click"exportExcel">导出</el-button> const exportExcel () > {const data [[商品, 单价, 数量, 总价],[A, 100, 1.55, { t: n, f: B2*C2…...
带你手写React中的useReducer函数。(底层实现)
文章目录 前言一、为什么需要 Reducer?二、Reducer 的核心概念1. Reducer 函数2. useReducer 钩子 三,手写react中的useReducer 总结 前言 在 React 开发中,useReducer 是管理复杂状态逻辑的利器。它类似于 Redux 的简化版,允许我…...

day024-网络基础-TCP与UDP、DNS
文章目录 1. 李导推荐书籍2. OSI七层模型2.1 传输层2.2 网络层2.2.1 问:两端处于不同局域网的设备怎么网络通信? 2.3 数据链路层2.4 物理层2.5 图解OSI七层模型 3. 数据传输模式3.1 全双工3.2 半双工3.3 单工 4. TCP 3次握手4.1 抓包 5. TCP 4次挥手5.1 …...

专场回顾 | 重新定义交互,智能硬件的未来设计
自2022年起,中国智能硬件行业呈现出蓬勃发展的态势,市场规模不断扩大。一个多月前,“小智AI”在短视频平台的爆火将智能硬件带向了大众视野,也意味着智能硬件已不再仅仅停留在概念和技术层面,而是加速迈向实际落地应用…...
如何把一台电脑作为另外一台电脑的显示器
https://zhuanlan.zhihu.com/p/703889583 1. 两台电脑都要进行:点开投影到此电脑,点击可选功能,在可选功能窗口,搜索无线显示器;在结果列表中选中无线显示器,并安装 2. 在笔记本电脑(要用来做…...

WPS 免登录解锁编辑
遇到 WPS 需要登录才能启用编辑功能? 如何免登录使用编辑功能? 方法一 解锁方法 1、关闭 WPS; 2、桌面右键→ “新建”→“文本文档”,粘贴以下内容(见最下面);编码保持默认(ANSI …...
【C/C++】线程安全初始化:std::call_once详解
std::call_once 使用详解 std::call_once 是 C11 标准库中提供的一个线程安全的一次性调用机制,位于 <mutex> 头文件中。它确保某个可调用对象只被执行一次,即使多个线程同时尝试调用它。 基本用法 #include <mutex> #include <thread…...

技术分享 | Oracle SQL优化案例一则
本文为墨天轮数据库管理服务团队第70期技术分享,内容原创,作者为技术顾问马奕璇,如需转载请联系小墨(VX:modb666)并注明来源。 一、问题概述 开发人员反映有条跑批语句在测试环境执行了很久都没结束&…...
什么是RFID电子标签
RFID 电子标签是用于物品标识、具有信息存储机制、能接收读写器的电磁场调制信号并返回响应信号的数据载体,通常被称为电子标签,也可称作射频卡、射频标签、射频卷标等,是与读写器一起构成 RFID 系统的硬件主体。 RFID 系统基本组成包括RFID电子标签、读写器、射频天线、应用…...

华为手机用的时间长了,提示手机电池性能下降,需要去换电池吗?平时要怎么用能让电池寿命长久一些?
华为手机提示电池性能下降时,是否需要更换电池以及如何延长电池寿命,取决于电池老化程度和使用习惯。以下是具体分析和建议: 一、是否需要更换电池? 电池健康度低于80% 如果手机提示“电池性能下降”,通常意味着电池…...

BERT***
1.预训练(Pre-training) 是深度学习中的一种训练策略,指在大规模无标注数据上预先训练模型,使其学习通用的特征表示,再通过微调(Fine-tuning) 适配到具体任务 2.sentence-lev…...

超级对话2:大跨界且大综合的学问融智学应用场景述评(不同第三方的回应)之二
摘要:《人机协同文明升维行动框架》提出以HIAICI/W公式推动认知革命,构建三大落地场景:1)低成本认知增强神经接口实现300%学习效率提升;2)全球学科活动化闪电战快速转化知识体系;3)人…...
在Linux环境里面,Python调用C#写的动态库,如何实现?
在Linux环境中,Python可以通过pythonnet(CLR的Python绑定)或subprocess调用C#动态库。以下是两种方法的示例: 方法1:使用pythonnet(推荐) 前提条件 安装Mono或.NET Core运行时安装pythonnet包…...