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

使用正则表达式提取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);
}
};

正则表达式解析

  1. /\/N\s+(\d+)/

    • /N: 匹配字面值"/N"
    • \s+: 匹配一个或多个空白字符
    • (\d+): 捕获组,匹配一个或多个数字
  2. /\/Count\s+(\d+)/

    • /Count: 匹配字面值"/Count"
    • \s+: 匹配一个或多个空白字符
    • (\d+): 捕获组,匹配一个或多个数字

优点与局限性

优点

  1. 实现简单,代码量少
  2. 无需引入额外依赖
  3. 性能较好,只需读取文件文本内容
  4. 适用于大多数标准PDF文件

局限性

  1. 可能无法处理某些特殊格式的PDF文件
  2. 对于加密或受保护的PDF文件可能无效
  3. 依赖PDF文件内部结构的一致性

错误处理建议

  1. 添加超时处理
typescript
const timeoutPromise = new Promise((, reject) => {
setTimeout(() => reject(new Error("获取页数超时")), 5000);
});
try {
const pageCount = await Promise.race([getPdfPageCount(file), timeoutPromise]);
} catch (error) {
// 处理错误
}
  1. 优雅降级
typescript
try {
const pageCount = await getPdfPageCount(file);
// 使用页数
} catch (error) {
console.warn("无法获取页数,继续上传流程");
// 继续处理
}

性能优化建议

  1. 限制读取大小
typescript
const content = e.target?.result as string;
const maxLength = Math.min(content.length, 5000); // 只读取前5000个字符
const partialContent = content.slice(0, maxLength);
  1. 缓存结果
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;
};

最佳实践建议

  1. 总是提供友好的错误提示
  2. 实现优雅降级,确保核心功能可用
  3. 添加适当的日志记录
  4. 考虑添加重试机制
  5. 注意内存使用,避免处理过大的文件

总结

使用正则表达式提取PDF页数是一种轻量级的解决方案,适用于大多数常见场景。虽然有一定局限性,但通过合理的错误处理和降级策略,可以在实际应用中很好地工作。对于要求更高的场景,可以考虑结合使用pdf.js等专业库。

参考资源

  1. PDF文件格式规范
  2. JavaScript FileReader API文档
  3. 正则表达式教程
  4. PDF.js项目文档

相关文章:

使用正则表达式提取PDF文件页数的实现方案

文章目录 背景介绍实现原理代码实现1. 基础函数结构2. 页数提取逻辑3. 使用示例 正则表达式解析优点与局限性优点局限性 错误处理建议性能优化建议最佳实践建议总结参考资源 背景介绍 在Web应用开发中,我们经常需要获取上传PDF文件的页数信息。虽然可以使用pdf.js等第三方库,但…...

Android实现RecyclerView边缘渐变效果

Android实现RecyclerView边缘渐变效果 1.前言&#xff1a; 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果&#xff0c;可以使RecyclerView的边缘在滚动时逐渐淡出或淡入&#xff0c;以提升用户体验。 2.Recyclerview属性&#xff1a; 2.1、requiresFading…...

springboot443旅游管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统旅游管理系统信息管理难度大&#xff0c;容错率低&#…...

利用git上传项目到GitHub

GitHub是基于git实现的代码托管。git是目前最好用的版本控制系统了&#xff0c;非常受欢迎&#xff0c;比之svn更好。 GitHub可以免费使用&#xff0c;并且快速稳定。 利用GitHub&#xff0c;你可以将项目存档&#xff0c;与其他人分享交流&#xff0c;并让其他开发者帮助你一…...

Rust之抽空学习系列(四)—— 编程通用概念(下)

Rust之抽空学习系列&#xff08;四&#xff09;—— 编程通用概念&#xff08;下&#xff09; 1、函数 函数用来对功能逻辑进行封装&#xff0c;能够增强复用、提高代码的可读 以下是函数的主要组成部分&#xff1a; 名称参数返回类型函数体 1.1、函数名称 在Rust中&…...

K-Means 聚类:数据挖掘的瑞士军刀

引言 在数据科学领域&#xff0c;聚类算法是一种非常重要的无监督学习方法&#xff0c;它能够帮助我们发现数据中的自然分组或模式。其中&#xff0c;K-Means 聚类算法因其简单高效而成为最常用的聚类算法之一。无论是市场细分、社交网络分析&#xff0c;还是图像分割等领域&a…...

项目练习:若依-前端项目的目录结构介绍

文章目录 一、目录截图二、目录讲解 一、目录截图 二、目录讲解 1、首先&#xff0c;我们可以看到&#xff0c;这个VUE项目&#xff0c;只有一个App.vue&#xff0c;所以&#xff0c;它是一个单页面系统。 这个App.vue是根组件&#xff0c;root组件。 2、public目录 在Vue 3.…...

知网研学 | 知网文献(CAJ+PDF)批量下载

知网文献&#xff08;CAJPDF&#xff09;批量下载 一、知网研学安装二、插件及脚本安装三、CAJ批量下载四、脚本下载及PDF批量下载浏览器取消拦截窗口 一、知网研学安装 批量下载知网文件&#xff0c;格式为es6文件&#xff0c;需使用知网研学软件打开&#xff0c;故需先安装该…...

设计模式期末复习

一、设计模式的概念以及分类 二、设计模式的主题和意图 三、面向对象程序设计原则&#xff0c;记住名字&#xff0c;还要理解它的使用场景以及如何用&#xff1f; 四、松耦合、紧耦合、强关联、弱关联、静态复用、动态复用的概念&#xff0c;还有静态委派&#xff0c;动态委…...

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服务 首先&#xff0c;需要停止Docker服务。使用systemctl命令来停止Docker服务&#xff1a; bash复制代码sudo systemctl stop docker二、卸载Docker软件包 接下来&#xff0c;使用CentOS的包管理器yum来卸载Docker软件包。根据安装的Docker版本和组件&#…...

css中相对定位的应用场景

元素位置微调 文本与图标组合微调&#xff1a;在网页设计中&#xff0c;经常会有文本和图标的组合&#xff0c;比如一个带有搜索图标的搜索框。可以使用相对定位来微调图标在搜索框内的位置。例如&#xff0c;有以下HTML结构&#xff1a; <input type"text" class…...

Android 获取屏幕物理尺寸

注&#xff1a;编译 sdk 需要使用 30 因为引入了 WindowMetrics、uild.VERSION_CODES.R 新 sdk 才存在的类和属性 某些场景处理 view &#xff0c;对 view 显示的位置要求比较精确&#xff0c;通常我们使用context.getResources().getDisplayMetrics().widthPixels 获取到的宽、…...

C缺陷与陷阱 — 8 编译与链接

目录 1 程序的编译过程 2 动态链接的优缺点 2.1 动态链接的优点 2.2 动态链接的缺点 2.3 只使用动态链接 3 函数库链接的5个特殊秘密 4 警惕Interpositioning 5 产生链接器报告文件 1 程序的编译过程 程序的编译过程是将源代码转换成计算机可以执行的机器代码的过程。…...

知识分享第三十天-力扣343.(整数拆分)

343 整数拆分 给定一个正整数 n&#xff0c;将其拆分为至少两个正整数的和&#xff0c;并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 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&#xff08;用于项目管理&#xff09; Spring Boot框架 DL4J库&#xff08;DeepLearning4J&#xff09; 创建 Spring Boot 项目 使用 Spring Initializr 来生成一个新的 Spring Boot 项目。选择合适的依赖&#xff0c;例如…...

SPL06 基于stm32F103 HAL库驱动(软件模拟IIC)

talk is cheap, show you my code SPL06.c #include "SPL06.h"//*************全局变量*************// Factor_List* b_list; //存储过采样率对应的系数KP&#xff0c;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从环境安装到训练的完整过程&#xff0c;本节主要介绍ONNX Runtime的原理以及使用其进行推理加速&#xff0c;使用Python、C两种编程语言来实现。 https://blog.csdn.net/MariLN/article/details/143924548?spm1001.2014.3001.5501 1. ONNX Ru…...

mfc140u.dll是什么文件?如何解决mfc140u.dll丢失的相关问题

遇到“mfc140u.dll文件丢失”的错误通常影响应用程序的运行&#xff0c;这个问题主要出现在使用Microsoft Visual C环境开发的软件中。mfc140u.dll是一个重要的系统文件&#xff0c;如果它丢失或损坏&#xff0c;会导致相关程序无法启动。本文将简要介绍几种快速有效的方法来恢…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...