正则表达式如何查找重复数字组 实现PDF数据字段提取
PDF文本姓名与工资金额提取方案
匹配逻辑说明
原始数据为固定双行分组结构:
- 奇数行:姓名文本,可能为2段(名+姓)或3段(名+中间名+姓),前后可能存在多余空格
- 偶数行:空格分隔的数字串,特征是目标工资金额对应的数字序列会连续重复出现2次,之后为个税扣缴数值无需提取
- 金额原始格式为「整数部分按千位拆分+小数后两位」,空格分隔,例如
13 359 25对应格式化后的$13,359.25,494 23对应$494.23
实现步骤
- 第一步:用正则按双行分组捕获,分别提取每行的姓名内容和数字内容
- 第二步:对数字序列做最长重复前缀检测,定位到重复出现两次的工资金额片段
- 第三步:将提取到的金额片段做格式化,拼接千分位逗号、美元符号和小数位,和姓名拼接得到最终结果
参考实现代码(JavaScript)
const rawData = ` NAME LAST 7 494 25 7 494 25 199 44 NAME LAST 4 488 00 4 488 00 109 07 NAME MIDDLE LAST 7 854 00 7 854 00 298 25 NAME LAST 494 23 494 23 12 01 NAME MIDDLE LAST 4 301 56 4 301 56 112 61 NAME M LAST 13 359 25 13 359 25 130 54`; const groupReg = /\s*([A-Z ]+?)\s*\n([\d ]+)/g; const output = []; let groupMatch; while ((groupMatch = groupReg.exec(rawData)) !== null) { const fullName = groupMatch[1].trim(); const numList = groupMatch[2].trim().split(/\s+/); // 定位重复的工资数字段 let segLength = 0; for (let len = Math.floor(numList.length / 2); len >= 1; len--) { const seg1 = numList.slice(0, len).join(' '); const seg2 = numList.slice(len, len * 2).join(' '); if (seg1 === seg2) { segLength = len; break; } } // 格式化金额 const wageSeg = numList.slice(0, segLength); const cents = wageSeg.pop(); const dollars = wageSeg.join('').replace(/\B(?=(\d{3})+(?!\d))/g, ','); const formattedWage = `$${dollars}.${cents}`; output.push(`${fullName} ${formattedWage}`); } // 打印最终结果 console.log(output.join('\n'));
执行输出
NAME LAST $7,494.25 NAME LAST $4,488.00 NAME MIDDLE LAST $7,854.00 NAME LAST $494.23 NAME MIDDLE LAST $4,301.56 NAME M LAST $13,359.25
说明:该方案没有硬编码金额数字段长度,可自动适配不同位数的工资金额,不会因为工资金额增大、千分位拆分数量变化导致匹配失效。
内容的提问来源于stack exchange,提问作者Outcast
相关产品推荐
相关产品推荐

