多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

在线文字数字提取全指南:正则、编码与OCR实操经验

在线文字数字提取全指南:正则、编码与OCR实操经验 “文字/数字提取”这五个字外行人觉得无非是复制粘贴真正做过的人才知道能有多烦。我从日志里抽过IP地址从Excel里把“总价89.90元”这种带单位的单元格拆成纯数字从报销票据截图里把金额录入系统还帮同事从一段URL查询串里把参数一个个抠出来。这些事单独写脚本吧有点小题大做一个个手动复制吧又慢又容易看错。所以我对“在线工具”这类东西的态度一直是真能用上。这篇文章就把我平时怎么用在线工具做文字/数字提取、怎么判断该用哪一类工具以及从编码校验到OCR识别这整条链路里的经验一起整理出来。无论你是文案、财务、运营还是程序员只要你经常和文本、表格、图片数据打交道都值得花几分钟把思路过一遍。先说结论在线工具适合单次、快速、数据量小的任务数据量一大、格式一复杂、内容一敏感我还是建议落到本地脚本。这背后不是“在线工具不靠谱”而是不同任务有不同的最优解。下面我就按“先从文本里提取数字/字符再到编码和校验、OCR图片识别最后讲讲几个衍生工具”的顺序把整个思路讲细。1. 首先想清楚你要提取的“东西”是哪一类1.1 纯文本中混着的数字和字母最典型的就是日志和表格。举个我上周遇到的例子一行销售明细写着“订单号A20240511001金额1234.5元数量2件”要提取订单号里的数字、金额数值和数量。乍一看很简单但如果有一千行每行格式还不完全一样手工提取就会出问题。这时候问题的本质就变成了“模式匹配”——你要告诉工具目标数字长什么样让它把所有符合形状的内容捞出来。在线工具里最通用的实现就是正则表达式这也是我后面会花大篇幅讲的东西。你可能觉得这种事Excel里的“分列”也能做但分列的前提是分隔符固定。现实中的数据往往很任性有时候数字前面是中文有时候后面跟着单位有时候金额带了千分位。正则的好处是它不看位置只看特征。我只要描述出“连续若干位数字”“小数点后可能跟两位”“前面有没有货币符号”它就能把符合条件的内容全部抓出来。在线正则工具最省心的地方是你写完表达式马上能看到结果不用先搭环境。1.2 带结构的内容里取某个字段从JSON、URL参数、HTML标签里提取字段比普通文本稍微复杂一点。比如一段JSON里有order_id: A12345你需要把A12345拿出来或者URL是https://example.com/pay?user10086amount99.9你要取出user和amount。这类内容有明确的键值结构在线工具通常提供JSON格式化、URL参数解析等功能点一下就能展开。我的建议是这类结构内容优先用专门工具而不是一上来就写正则。为什么因为JSON可以嵌套很多层正则匹配括号和层级很容易出错而JSON解析工具会先把结构树展示出来你再沿着键名一层层找结果准确得多。同理URL参数看起来简单但有可能出现编码后的中文、特殊字符、重复键名直接肉眼复制的错误率也不低。提取的最终目的是拿到干净可用的字段不是证明自己能用正则硬啃所以选工具要选匹配问题类型的。1.3 照片和扫描件里的字符图片里的字靠复制粘贴是拿不到的得用OCR。票据、截图、拍照的文档都可以。OCR的核心是图像识别它会先定位文字区域再逐个字符判断。在线OCR工具的优势是开箱即用不用配环境适合偶尔处理几张图的场景。我平时遇到最多的就是发票金额提取、截图里的报错信息翻录以及纸质文档的电子化录入。这里要提醒一句OCR识别出来的内容千万不能直接当成最终答案。图片清晰度、字体、排版都会影响识别率尤其是数字和小数点。我自己处理票据的流程是“识别、对照、手工校对”三步就算在线工具自信满满给出结果我也会对着原图把数字、单位再核一遍。后面第四章我会专门讲OCR实操这里先把场景区分清楚。2. 正则表达式在线提取工具的核心引擎2.1 正则到底是怎么匹配的正则表达式就是一串“描述字符形状”的规则。比如\d表示数字字符\d{3}表示连续三位数字[A-Z]表示一个大写字母。你不用背很多记住几个基础符号就能处理绝大多数提取需求。用生活类比来解释如果文本是一堆糖豆正则就像筛子\d这种表达式是专门筛数字的筛子\w是筛字母数字下划线的筛子[0-9]{2}是只筛两位数的筛子。筛子孔的形状决定了你能捞起什么。正则有“字符类”“量词”“分组”“锚点”几个核心概念。字符类决定匹配什么类型量词决定匹配多少次分组决定结果怎么切分锚点决定从哪里开始。理解这四块基本就能应付百分之八十的提取需求。其余的断言、反向引用、贪婪与懒惰属于优化和防误伤的手段遇到具体问题再学也来得及。2.2 高频提取规则速查表目标内容常用表达式说明连续数字\d提取正整数、纯数字串带小数点数字\d(\.\d{1,2})?匹配整数或保留一两位小数手机号1[3-9]\d{9}11位第二位限制在3-9邮箱[\w.-][\w-](\.[\w-])常见邮箱格式IPv4地址(\d{1,3}\.){3}\d{1,3}提取IP是否合法需另行校验日期\d{4}-\d{2}-\d{2}匹配“2024-05-11”这类格式金额带货币符号[¥$]\s?\d(\.\d{1,2})?人民币/美元金额表格里的表达式可以直接复制到在线正则工具里试但我建议不要原封不动用在生产环境中。真实文本里可能出现全角数字、千分位、空格、制表符甚至各种不可见字符表达式必须结合上下文调整。比如手机号表达式只匹配11位且第二位是3-9但如果一段文本里同时有手机号和固话你就得用分隔符锚点限制边界否则会从固话号码里截出可疑的11位片段。先把表当作速查验证思路再用真实样本做回归这才是稳妥的用法。2.3 在线正则提取的正确打开方式假设有一段日志需要提取日期、IP地址和金额2024-05-11 10:32:18 INFO user10086 ip192.168.1.10 amount1234.56在在线正则工具中我一般按这个顺序操作把日志文本粘贴到“待匹配文本”区域。在正则框输入(?date\d{4}-\d{2}-\d{2})\s(?time\d{2}:\d{2}:\d{2}).*?ip(\d{1,3}\.){3}\d{1,3}.*?amount(\d(\.\d{1,2})?)打开“全局匹配”开关让工具不要匹配到第一个就停下。查看匹配结果列表工具会把每一处命中的内容按捕获组分开显示。这里的(?date...)是命名捕获组方便结果输出时直接对应到“日期”字段。.*?表示非贪婪匹配任意字符意思是点到为止避免把整行都吞进去。如果你只需要IP后面的四段数字可以给IP表达式整体加一组括号然后只输出对应捕获组。看结果时也要注意大部分在线正则工具会同时显示“完整匹配”和“捕获组”。完整匹配通常包含前后文的无用内容比如ip192.168.1.10里的ip捕获组才是你真正想提取的字段。如果你不加括号工具就只能给你完整匹配后续还得手工清理。所以我写提取正则的习惯是能加分组的地方尽量加分组尤其是需要从同一行里提取多个字段的时候。2.4 几个容易踩的坑第一不同工具的正则引擎不一样。有的默认按JavaScript处理有的按PCRE处理还有的用Python的re模块。\d在多数引擎都表示数字但零宽断言、命名捕获组的写法有差异。比如JavaScript早期版本不支持(?name...)这种命名捕获组你在一个工具里写得好好的表达式换到另一个工具就报错。粘贴别人表达式之前先确认引擎类型。第二大段文本里的换行符。默认情况下.不匹配换行如果匹配目标跨行需要开启“点号匹配换行”选项或者改用[\s\S]*?这种写法。很多新手把多行日志粘进去发现明明有目标却匹配不到多半就是这个原因。第三贪婪与懒惰。.*是贪婪的可能从第一个目标一直匹配到最后一个目标.*?是懒惰的匹配到满足条件的最小范围。提取时我一般先用懒惰匹配避免多抓。举例来说文本“开始123结束开始456结束”用开始.*结束会抓出整段“开始123结束开始456结束”而开始.*?结束只会分别得到“开始123结束”和“开始456结束”。第四中文内容。想提取“姓名张三”中的张三用姓名([\u4e00-\u9fa5])比姓名(.)更不容易误伤因为后者会把后面的标点、换行甚至下一段内容都带进捕获组。中文标点、全角空格也会干扰匹配遇到奇怪结果时先把文本里的不可见字符显示出来看一眼。3. 别急着用结果编码、进制、校验码和密文的再提取3.1 提取出来的数字可能只是“中间形态”很多场景下提取的数字并不是最终答案。比如日志里出现0x1F你提取到1F但它表示的真正含义是十进制31。再比如URL里的%E6%96%87是一种编码后的中文HTML里的#25991;是字符实体。如果你把十六进制数当普通数字处理把URL编码当乱码丢弃后面的工作就会出大问题。所以我处理提取任务时养成了一个习惯先问一句“这个数字是什么进制、什么编码”再决定要不要转换。收到一条看似乱码的字符串先别删除去看它有没有%、\u、0x、#这些特征。在线工具站里通常有对应的解析选项点一下就能还原。这一步做对了后面就能少走弯路。3.2 进制转换与URL编码还原在线工具站里最常见的字符处理小组就是进制转换和编码解码。二进制、八进制、十进制、十六进制互转几秒钟出结果。处理中文乱码时我会先看文本里有没有%、\u、0x这些特征分别对应URL编码、Unicode转义、十六进制字节流。举个例子一段接口日志里返回\u5f00\u59cb在线Unicode转换工具会立刻显示“开始”。再比如抓包时看到%E6%8F%90%E5%8F%96用URL解码得到“提取”。这些操作本质也是“提取”——把编码层的信息还原成人能读的文字。具体到在线工具的使用无非是把编码串粘进输入框选对解码方式点击转换。要注意的是同一个%E6%8F%90%E5%8F%96在不同字符集下解出来的内容可能不同优先选UTF-8除非你知道上游明确用了GBK。进制转换也是同样的逻辑。十六进制数1F与十进制数31只是同一数值的不同表示方式。提取出来后要不要转取决于你拿它去干什么。比如设备地址、颜色值、寄存器数值经常以十六进制形式出现在日志里这时转成十进制通常会更容易判断。3.3 Modbus校验码在线计算工业调试刚需做设备通信的人对“Modbus”这个协议应该不陌生。Modbus RTU报文在发送前需要计算CRC16校验码很多在线工具专门提供“Modbus校验码计算器”。我不打算把这个讲得太深但使用步骤有必要给现场调试的朋友记录一下在报文输入框填写十六进制数据。以01 06 00 01 00 17为例这是功能码06写单个寄存器的请求。选择“Modbus CRC16”算法。点击计算得到两个字节的校验值。注意在线工具的输出顺序有的显示“CRC低位在前”有的“高位在前”实际拼接报文时要按协议要求来。按Modbus RTU的约定发送时CRC低字节通常放在报文末尾高字节在后。在线工具一般会给出顺序提示你直接照它说的拼接即可。如果测出通信数据校验不过第一反应不是怀疑工具而是检查输入的报文是不是少了空格、多了前缀0x或者把ASCII码当成十六进制数填进去了。这类小问题在实际排查里出现频率极高。顺便说一句不少在线校验码工具还支持CRC32、CRC8、MD5、SHA1等算法。对工业调试来说Modbus CRC16只是其中之一但思路完全一致把数据交给工具工具负责计算累加值或多项式余数你只管拿着结果去和设备交互。校验码这种东西手算几乎没有必要用工具反而是保证可靠性的方式。3.4 Jasypt在线解密配置脱敏后的合法还原Jasypt是Java生态里常用的加密库很多系统的配置文件里会把密码写成ENC(密文)这样运维在查看配置时不会直接看到明文。我见过不少同事第一次看到ENC(...)不知道怎么办以为密码烂了。实际上只要知道当初的加密算法和密钥就能用在线Jasypt工具还原。使用时要选对算法常见的有PBEWithMD5AndDES、PBEWithHmacSHA256AndAES等然后填入密文、密钥必要时还要加IV向量点击解密就能得到明文。这里必须强调这个操作只适用于你自己负责的系统、你被授权查看的配置。拿别人的密文去胡乱试既不合法也不道德。在线工具有时会保存提交记录涉及生产环境的敏感配置建议不要提交到公共网站改用本地命令行验证。安全第一别图一时省事。3.5 猪圈密码理解字符映射的趣味案例我看不少在线工具站里还收录了“猪圈密码加密”这种古典密码工具。猪圈密码本质上是用一套网格符号替换字母加密就是把字母换成对应符号解密就是反过来。用在线工具输入“HELLO”你会得到一串由点和折线组成的符号。这个工具实用性不强但适合作为理解“提取-映射”的入门案例。你从密文里提取到的是符号要还原文字需要一张映射表。所谓解码很多情况下就是“提取按规则替换”这和正则提取、进制转换在思路上完全一致。搞清楚这条线以后遇到再奇怪的编码也不会慌先找规则再找工具。4. 图片变文字OCR在线提取的完整流程4.1 选在线OCR还是本地识别偶尔处理两三张截图用在线OCR完全够要是天天批量处理几百张发票我更推荐本地工具比如PaddleOCR、Tesseract配合脚本可以批量跑。在线OCR的好处是不用装驱动、不用配模型上传就能识别。坏处是文件大小和隐私有限制大图会超时过于敏感的内容我坚决不上传。我的原则很简单一次性、不敏感用在线工具批量、敏感、需要精度用本地脚本。这个原则在后边的“隐私”小节还会再强调。很多人纠结“哪个在线OCR识别率最高”其实识别率跟你上传的图片质量关系更大。同一款工具你给一张清晰、端正、无干扰的图它肯定比模糊倾斜的原图表现好得多。4.2 从一张票据图片提取金额的实操假设我手头有一张报销票据截图上面有一行“合计 RMB 1,234.56”。具体步骤如下打开在线OCR页面上传图片。工具会自动识别整张图片的文字也会提供“选择区域”功能。我通常先用自动识别看全貌再用区域识别单独锁定金额那一行。校对识别结果金额里的逗号和点号极容易认错1,234.56如果被识别成1234.56或1.234.56都有问题。复制结果到目标系统。OCR只是一个录入辅助数字的校验不能省。小数点位置差一位金额就差了100倍在线工具不会替你判断业务合不合理。我在实际处理里甚至遇到过把“8”识别成“3”的情况这时候如果直接粘贴到报销系统后面财务对账就会很痛苦。所以无论在线工具提示“识别成功”我都会至少扫一遍原图里的数字。4.3 识别不准时按这个顺序排查如果识别结果乱码先别急着怀疑OCR工具按照下面四个方向排查大多数情况都能解决清晰度图片是否被压缩过、字是不是太小。可以放大2倍再传一次。倾斜扫描件歪了先旋转纠偏。背景有底色、水印或阴影时识别准确率会明显下降可以先用图像工具做去底色或增强对比度。中英文混合中文OCR和英文OCR模型侧重点不同混合文本选通用模型或者分两次识别再合并。这套排查顺序能解决大约八成的问题。剩下两成靠人工校对兜底没什么丢人的OCR也不是人眼替代品。尤其是一些特殊字体、艺术字、手写体识别率本来就不高别指望工具能“硬读”出来。我的经验是先花几秒钟把图处理一下比反复换在线工具更有效。4.4 传图前先过一遍隐私这一点我必须多说两句。身份证、合同、财务报表这类含敏感信息的图片不要随手传到任何公共在线OCR平台。在线服务的便利背后意味着提交的数据会经过第三方服务器有没有被留存你无法控制。如果一定要提取这类图片里的文字两个办法一是先对图片做脱敏把不需要识别的身份证号、地址、签字区域用色块盖住只保留需要识别的部分二是改用本地OCR工具比如开源的PaddleOCR在自己的机器上识别数据不出本地。处理敏感数据时少一点便利多一分稳妥。我见过有人为了识别一张合同上的电话号码把整页合同传上去结果公司信息、联系人、盖章全暴露了。这个习惯非常不好。5. 聚合工具站的隐藏用法从在线IDE到等时圈5.1 同样是“在线工具站”差别可以很大现在网上有大量在线工具聚合站像nbtools在线工具这种名字你可能见过。它们把时间戳转换、UUID生成、Base64、正则、进制转换、图片压缩、单位换算都放在一起。我视它们为“临时工具箱”尤其是电脑上没装专业软件的时候一个页面能搞定八成琐碎需求。我选聚合工具站有三条标准加载快、没诱导下载、页面尽可能干净。很多工具站常换域名书签可能没过多久就失效所以不要依赖某一个站点而是需要什么功能的时候临时搜一下。对于代码类、数据类需求我还会配合“在线运行代码”的站点一起用。本质上工具站的价值不是某一个功能多强而是把你频繁用到的零碎能力集中到同一个入口减少切换成本。5.2 用在线代码运行工具验证提取逻辑有时我不确定一段正则表达式在新语言里是否好用也不想为这事单独开一个IDE就在支持代码在线运行的工具里直接跑。比如想验证Python里提取数字的写法代码很简单import re text 订单号A20240511001金额1234.5元 print(re.findall(r\d, text))选择Python环境点击运行马上能看到结果[20240511001, 1234, 5]。在线代码工具同样适合处理MATLAB算法验证比如计算一个矩阵的均值或者画个简单曲线不需要提前安装大型软件。这种“临时验证”思路能让我在线提取文本时少犯低级错误。正则表达式、脚本逻辑先在在线环境里跑通再移植到真实项目中效率会高很多。有人会问既然有了在线工具为什么还要在线代码运行我的回答是在线工具适合“填参数点按钮”一旦你需要循环、条件判断、文件读写就需要编程环境了。比如要统计一个日志文件里哪些IP出现次数最多在线正则工具只能帮你把IP全部提取出来统计还得靠代码。这时候一个在线Python环境就够用。5.3 驾车等时圈把数字变成地理决策还有一个比较冷门但特别有意思的工具驾车等时圈。它做的事情很简单输入一个地点坐标或地址再选择15分钟、30分钟、60分钟等时间阈值马上生成一张地图多边形表示开车在这个时间内能到达的区域。我见过房产中介拿来分析小区配套开店的人拿它评估商圈覆盖范围也有人用它规划通勤路线。从“数字提取”的视角看等时圈工具的输入也是数字坐标、时间、道路速度输出是一张可视化的范围图。本质上它把一组数字转换成了空间决策信息。如果你在处理地理文本比如从地址文本里提取经纬度再交给在线等时圈工具做分析整个过程和“文本提取在线加工”是一致的。5.4 从Heapdump里提取内存中的字符串最后提一个开发场景Java进程发生OOM时会产生heapdump文件。排查这类文件通常要分析里面有哪些对象占用内存、哪些字符串对象特别异常。在线heapdump分析工具可以上传较小的dump文件并自动给出类实例数量、对象大小排行、字符串去重结果等信息。我实际接触过一个案例一台服务频繁Full GC把heapdump传到在线分析工具后发现一个缓存Map里塞了几百万个重复的字符串占用了将近80%的堆内存。这个结论在工具里一眼就能看出来不需要装VisualVM。需要提醒的是heapdump文件一般很大动不动几百MB在线工具只适合处理脱敏后的小文件。包含用户信息、密钥的对象字符串上传前要想清楚。大型dump或者敏感数据还是用本地工具分析更稳妥。6. 我这些年用在线提取工具的习惯6.1 先定规则再点按钮在线工具最容易让人上头的就是“随手试”。我现在的做法是粘贴数据之前先花十秒钟想清楚目标字符的边界。比如提取账号到底要几位数可能包含字母吗前后分隔符是什么把这个规则写在草稿纸上再去找对应工具成功率会高很多。规则明确以后正则用起来也顺手。我所有的提取需求都会先尝试整理成“边界条件”不知道怎么描述边界就用分隔符锚点来做。比如要提取冒号后的数值就写:\s*(\d)要提取等号右边的字母数字串就写\s*([A-Za-z0-9_])。这个习惯让我从“到处翻工具”变成了“先思考再操作”。6.2 敏感数据一条铁律我在前面提过几次隐私这里再总结成一条铁律凡是可能识别到个人身份、企业机密、系统凭证的内容一律不在公共在线工具里处理。不是说在线工具一定不靠谱而是你无法控制数据离开你电脑之后的去向。电子邮件、手机号、身份证号、银行卡号、内部系统地址、数据库连接串这些内容一旦被第三方留存风险是不可逆的。为了图省事不值得。遇到这类数据我的做法是要么用本地脚本或本地工具解决要么提前脱敏去掉中间的几位数字让数据不再具备“可识别性”。例如手机号可以改成138****1234邮箱改成a***example.com。脱敏之后再上传在线工具既保住了便利又降低了泄露风险。安全习惯比工具本身更重要。6.3 把在线工具和本地脚本组合起来最有效率的一条其实是组合使用。单次提取、数据量小、格式乱我用在线正则工具或OCR快速解决。批量处理、数据量大、隔三差五就要重复我一定写本地脚本。例如要从一千行文本里提取手机号我根本不会打开在线工具而是用Python写一行re.findall(r1[3-9]\d{9}, open(data.txt, encodingutf-8).read())在线工具负责“快速验证”脚本负责“可靠落地”两者配合才是效率最大化。我还会把常用表达式、常用工具都整理成一个笔记文件每次遇到类似需求先翻笔记。时间久了你会发现需要反复搜索的东西就那么多沉淀下来以后处理各种提取需求会越来越稳。
返回列表