使用正则表达式提取PDF文件页数的实现方案
文章目录
- 背景介绍
- 实现原理
- 代码实现
- 1. 基础函数结构
- 2. 页数提取逻辑
- 3. 使用示例
- 正则表达式解析
- 优点与局限性
- 优点
- 局限性
- 错误处理建议
- 性能优化建议
- 最佳实践建议
- 总结
- 参考资源
背景介绍
在Web应用开发中,我们经常需要获取上传PDF文件的页数信息。虽然可以使用pdf.js等第三方库,但这些库通常比较重量级。本文将介绍一种使用正则表达式直接解析PDF文件内容来获取页数的轻量级方案。
实现原理
PDF文件虽然是二进制格式,但其内部结构是基于文本的。PDF文件中通常包含类似 /N 10 或 /Count 10 这样的标记来记录总页数。我们可以通过正则表达式来匹配这些标记并提取页数信息。
代码实现
1. 基础函数结构
typescript
const getPdfPageCount = (file: File): Promise<number> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (e) => {
// 解析逻辑
};
reader.onerror = () => reject(new Error("读取文件失败"));
reader.readAsText(file);
});
};
2. 页数提取逻辑
typescript
reader.onload = (e) => {
try {
const content = e.target?.result as string;
// 方法1: 匹配 /N 格式
const matches = content.match(/\/N\s+(\d+)/);
if (matches && matches[1]) {
const pageCount = parseInt(matches[1], 10);
if (pageCount > 0) {
return resolve(pageCount);
}
}
// 方法2: 匹配 /Count 格式
const countMatches = content.match(/\/Count\s+(\d+)/);
if (countMatches && countMatches[1]) {
const pageCount = parseInt(countMatches[1], 10);
if (pageCount > 0) {
return resolve(pageCount);
}
}
reject(new Error("无法获取PDF页数"));
} catch (error) {
reject(error);
}
};
3. 使用示例
typescript
const beforeUpload = async (file) => {
try {
const pageCount = await getPdfPageCount(file);
console.log("PDF页数:", pageCount);
} catch (error) {
console.error("获取页数失败:", error);
}
};
正则表达式解析
-
/\/N\s+(\d+)//N: 匹配字面值"/N"\s+: 匹配一个或多个空白字符(\d+): 捕获组,匹配一个或多个数字
-
/\/Count\s+(\d+)//Count: 匹配字面值"/Count"\s+: 匹配一个或多个空白字符(\d+): 捕获组,匹配一个或多个数字
优点与局限性
优点
- 实现简单,代码量少
- 无需引入额外依赖
- 性能较好,只需读取文件文本内容
- 适用于大多数标准PDF文件
局限性
- 可能无法处理某些特殊格式的PDF文件
- 对于加密或受保护的PDF文件可能无效
- 依赖PDF文件内部结构的一致性
错误处理建议
- 添加超时处理
typescript
const timeoutPromise = new Promise((, reject) => {
setTimeout(() => reject(new Error("获取页数超时")), 5000);
});
try {
const pageCount = await Promise.race([getPdfPageCount(file), timeoutPromise]);
} catch (error) {
// 处理错误
}
- 优雅降级
typescript
try {
const pageCount = await getPdfPageCount(file);
// 使用页数
} catch (error) {
console.warn("无法获取页数,继续上传流程");
// 继续处理
}
性能优化建议
- 限制读取大小
typescript
const content = e.target?.result as string;
const maxLength = Math.min(content.length, 5000); // 只读取前5000个字符
const partialContent = content.slice(0, maxLength);
- 缓存结果
typescript
const pageCountCache = new Map();
const getCachedPageCount = async (file: File) => {
const fileId = file.name + file.size; // 简单的文件标识
if (pageCountCache.has(fileId)) {
return pageCountCache.get(fileId);
}
const pageCount = await getPdfPageCount(file);
pageCountCache.set(fileId, pageCount);
return pageCount;
};
最佳实践建议
- 总是提供友好的错误提示
- 实现优雅降级,确保核心功能可用
- 添加适当的日志记录
- 考虑添加重试机制
- 注意内存使用,避免处理过大的文件
总结
使用正则表达式提取PDF页数是一种轻量级的解决方案,适用于大多数常见场景。虽然有一定局限性,但通过合理的错误处理和降级策略,可以在实际应用中很好地工作。对于要求更高的场景,可以考虑结合使用pdf.js等专业库。
参考资源
- PDF文件格式规范
- JavaScript FileReader API文档
- 正则表达式教程
- PDF.js项目文档
相关文章:
使用正则表达式提取PDF文件页数的实现方案
文章目录 背景介绍实现原理代码实现1. 基础函数结构2. 页数提取逻辑3. 使用示例 正则表达式解析优点与局限性优点局限性 错误处理建议性能优化建议最佳实践建议总结参考资源 背景介绍 在Web应用开发中,我们经常需要获取上传PDF文件的页数信息。虽然可以使用pdf.js等第三方库,但…...
Android实现RecyclerView边缘渐变效果
Android实现RecyclerView边缘渐变效果 1.前言: 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果,可以使RecyclerView的边缘在滚动时逐渐淡出或淡入,以提升用户体验。 2.Recyclerview属性: 2.1、requiresFading…...
springboot443旅游管理系统(论文+源码)_kaic
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统旅游管理系统信息管理难度大,容错率低&#…...
利用git上传项目到GitHub
GitHub是基于git实现的代码托管。git是目前最好用的版本控制系统了,非常受欢迎,比之svn更好。 GitHub可以免费使用,并且快速稳定。 利用GitHub,你可以将项目存档,与其他人分享交流,并让其他开发者帮助你一…...
Rust之抽空学习系列(四)—— 编程通用概念(下)
Rust之抽空学习系列(四)—— 编程通用概念(下) 1、函数 函数用来对功能逻辑进行封装,能够增强复用、提高代码的可读 以下是函数的主要组成部分: 名称参数返回类型函数体 1.1、函数名称 在Rust中&…...
K-Means 聚类:数据挖掘的瑞士军刀
引言 在数据科学领域,聚类算法是一种非常重要的无监督学习方法,它能够帮助我们发现数据中的自然分组或模式。其中,K-Means 聚类算法因其简单高效而成为最常用的聚类算法之一。无论是市场细分、社交网络分析,还是图像分割等领域&a…...
项目练习:若依-前端项目的目录结构介绍
文章目录 一、目录截图二、目录讲解 一、目录截图 二、目录讲解 1、首先,我们可以看到,这个VUE项目,只有一个App.vue,所以,它是一个单页面系统。 这个App.vue是根组件,root组件。 2、public目录 在Vue 3.…...
知网研学 | 知网文献(CAJ+PDF)批量下载
知网文献(CAJPDF)批量下载 一、知网研学安装二、插件及脚本安装三、CAJ批量下载四、脚本下载及PDF批量下载浏览器取消拦截窗口 一、知网研学安装 批量下载知网文件,格式为es6文件,需使用知网研学软件打开,故需先安装该…...
设计模式期末复习
一、设计模式的概念以及分类 二、设计模式的主题和意图 三、面向对象程序设计原则,记住名字,还要理解它的使用场景以及如何用? 四、松耦合、紧耦合、强关联、弱关联、静态复用、动态复用的概念,还有静态委派,动态委…...
CentOS7源码编译安装nginx+php+mysql
1.安装nginx 安装依赖 yum -y install gcc gcc-c wget automake autoconf libtool libxml2-devel libxslt-devel perl-devel perl-ExtUtils-Embed pcre-devel openssl openssl-devel 创建一个不能登录的nginx运行用户 groupadd www-data useradd -s /sbin/nologin -g www-d…...
linux CentOS系统上卸载docker
一、停止Docker服务 首先,需要停止Docker服务。使用systemctl命令来停止Docker服务: bash复制代码sudo systemctl stop docker二、卸载Docker软件包 接下来,使用CentOS的包管理器yum来卸载Docker软件包。根据安装的Docker版本和组件&#…...
css中相对定位的应用场景
元素位置微调 文本与图标组合微调:在网页设计中,经常会有文本和图标的组合,比如一个带有搜索图标的搜索框。可以使用相对定位来微调图标在搜索框内的位置。例如,有以下HTML结构: <input type"text" class…...
Android 获取屏幕物理尺寸
注:编译 sdk 需要使用 30 因为引入了 WindowMetrics、uild.VERSION_CODES.R 新 sdk 才存在的类和属性 某些场景处理 view ,对 view 显示的位置要求比较精确,通常我们使用context.getResources().getDisplayMetrics().widthPixels 获取到的宽、…...
C缺陷与陷阱 — 8 编译与链接
目录 1 程序的编译过程 2 动态链接的优缺点 2.1 动态链接的优点 2.2 动态链接的缺点 2.3 只使用动态链接 3 函数库链接的5个特殊秘密 4 警惕Interpositioning 5 产生链接器报告文件 1 程序的编译过程 程序的编译过程是将源代码转换成计算机可以执行的机器代码的过程。…...
知识分享第三十天-力扣343.(整数拆分)
343 整数拆分 给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 1: 输入: 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: 10 输出: 36 解释: 10 3 3 4, 3 3 4 36。 说明: 你可…...
Springboot 整合DL4J 打造智能写作助手(文本生成)
项目准备 环境要求: Java 1.8或以上 Maven 或 Gradle(用于项目管理) Spring Boot框架 DL4J库(DeepLearning4J) 创建 Spring Boot 项目 使用 Spring Initializr 来生成一个新的 Spring Boot 项目。选择合适的依赖,例如…...
SPL06 基于stm32F103 HAL库驱动(软件模拟IIC)
talk is cheap, show you my code SPL06.c #include "SPL06.h"//*************全局变量*************// Factor_List* b_list; //存储过采样率对应的系数KP,KT COEF_ValueStruct Coefficient { 0 }; //存储校准系数…...
【C#】List求并集、交集、差集
值类型List List<int> intList1 new List<int>() { 1, 2, 3 };List<int> intList2 new List<int>() { 3, 4, 5 };var result intList1.Union(intList2);Console.WriteLine($"并 {string.Join(,,result)}");result intList1.Intersect(in…...
YOLOv8目标检测——详细记录使用ONNX Runtime进行推理部署C++/Python实现
概述 在之前博客中有介绍YOLOv8从环境安装到训练的完整过程,本节主要介绍ONNX Runtime的原理以及使用其进行推理加速,使用Python、C两种编程语言来实现。 https://blog.csdn.net/MariLN/article/details/143924548?spm1001.2014.3001.5501 1. ONNX Ru…...
mfc140u.dll是什么文件?如何解决mfc140u.dll丢失的相关问题
遇到“mfc140u.dll文件丢失”的错误通常影响应用程序的运行,这个问题主要出现在使用Microsoft Visual C环境开发的软件中。mfc140u.dll是一个重要的系统文件,如果它丢失或损坏,会导致相关程序无法启动。本文将简要介绍几种快速有效的方法来恢…...
Git报‘dubious ownership’错误?除了safe.directory,还有这3种更灵活的权限管理姿势
Git权限管理进阶:超越safe.directory的四种灵活解决方案 当你从团队仓库克隆代码到本地,正准备提交修改时,突然遭遇dubious ownership错误——这种场景对中高级开发者而言绝不陌生。Git的安全机制本意是保护项目免受未授权修改,但…...
告别裸机延时!ESP32-C3/ESP32-S3用RMT外设精准驱动WS2812B灯带(Arduino/IDF双平台教程)
ESP32-C3/ESP32-S3 RMT外设驱动WS2812B灯带实战指南 当你的灯光项目从十几颗WS2812B升级到上百颗时,GPIO模拟驱动方式很快就会遇到瓶颈——闪烁、卡顿、颜色失真,这些问题的根源在于时序精度不足。ESP32系列芯片内置的RMT(Remote Control&…...
5分钟极速上手:通达信缠论可视化插件终极指南
5分钟极速上手:通达信缠论可视化插件终极指南 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 你是否曾经面对复杂的K线图感到困惑?是否想学习缠论分析但被繁琐的笔段划分吓退&…...
拯救你的C盘空间:用FreeMove实现无痛文件迁移的完整指南
拯救你的C盘空间:用FreeMove实现无痛文件迁移的完整指南 【免费下载链接】FreeMove Move directories without breaking shortcuts or installations 项目地址: https://gitcode.com/gh_mirrors/fr/FreeMove 你是否经常看到C盘变红的警告,却不敢随…...
掌握这四大趋势,让你的AI Agent真正“能干活”!CSDN收藏必备指南
本文深入探讨了企业级AI Agent的四大核心趋势:MCP协议实现可扩展集成、GraphRAG提升回答一致性、AgentDevOps确保行为质量与推理链路稳定性、RaaS模式实现结果计费。文章指出,这些趋势共同推动AI Agent从“可用”到“好用”的跨越,并提供了实…...
Cool-Request终极指南:如何高效配置全局请求头提升API测试效率
Cool-Request终极指南:如何高效配置全局请求头提升API测试效率 【免费下载链接】cool-request IDEA API、Java Method debug tools 项目地址: https://gitcode.com/gh_mirrors/co/cool-request 在Java API开发和调试过程中,Cool-Request作为一款强…...
[GESP202512 C++ 三级] 选择题第 8 题 ← unsigned int
【题目描述】 在一个特定的计算机系统中,假如 unsigned int 类型需要占用2个字节的存储空间(每个字节有8位),则 unsigned int 可以表示的数据范围是( A ) A. 0 ~ 65535 B. 0 ~ 65536 C. -65536 ~ 655…...
React极简表单库veyra-forms:轻量级、类型安全的表单状态管理方案
1. 项目概述:一个被低估的轻量级表单解决方案在Web开发的世界里,表单处理是个既基础又麻烦的活儿。从简单的联系表单到复杂的多步骤数据收集,开发者们总是在寻找一个平衡点:既要功能强大、易于集成,又要足够轻量、不拖…...
一键部署本地大模型:基于vLLM与Hermes的AI对话服务搭建指南
1. 项目概述与核心价值最近在折腾本地大语言模型(LLM)部署的朋友,估计都绕不开一个名字:Hermes。这个名字背后,通常指的是由 NousResearch 团队发布的 Hermes 系列模型,它们以出色的指令遵循能力和对话质量…...
从EGO-Planner到集群协同:分布式轨迹优化在无人机编队中的应用
1. 项目概述:从单机到集群的自主飞行进化如果你玩过无人机,或者关注过机器人领域,大概会知道让一台机器在空中自主规划路径、避开障碍物已经是个不小的挑战。那么,想象一下,让一群无人机像鸟群一样,在复杂、…...
