使用node-smpp如何高效解析SMPP DLR响应的stat字段?
高效解析SMPP DLR投递报告的实用方案
嘿,做SMPP对接时解析DLR确实容易踩坑,尤其是直接用空格/冒号分割的话,碰到text字段带空格或者键名带空格(比如submit date)就会出错。给你分享几个更健壮的方案:
1. 正则表达式(最推荐,适配所有标准DLR格式)
写一个精准匹配键值对的正则,能自动识别带空格的键和值,完美处理各种边界情况:
const dlrString = 'id:355e917d-xxxx-xxxx-xxxx-xxxxxxxxxxxx sub:001 dlvrd:001 submit date:2012191607 done date:2012191607 stat:DELIVRD err:000 text:Hello World!'; // 正则逻辑:匹配"键:值",直到下一个"键:"或者字符串结束 const dlrRegex = /(\S+(?:\s+\S+)?):(.*?)(?=\s+\S+:|$)/g; const dlrResult = {}; let match; while ((match = dlrRegex.exec(dlrString)) !== null) { // 把带空格的键转成下划线命名(比如submit date → submit_date) const key = match[1].replace(/\s+/g, '_'); dlrResult[key] = match[2].trim(); } console.log(dlrResult.stat); // 输出 DELIVRD console.log(dlrResult.text); // 输出 Hello World!
这个正则能完美识别submit date这种带空格的键,也不会把text字段里的空格当成分割符,是最健壮的方案。
2. 自定义解析函数(代码更直观)
如果觉得正则有点难读,可以写一个分步处理的函数,先处理带空格的键,再分割键值对:
function parseDLR(dlrStr) { const dlrObj = {}; // 先把带空格的键替换成下划线形式,避免分割错误 const processedStr = dlrStr .replace('submit date:', 'submit_date:') .replace('done date:', 'done_date:'); // 只分割"键:"前面的空格,不会拆分text字段 const keyValuePairs = processedStr.split(/\s+(?=\S+:)/); keyValuePairs.forEach(pair => { const [key, ...valueSegments] = pair.split(':'); // 处理值里可能带冒号的情况(虽然DLR里很少见,但防患于未然) dlrObj[key] = valueSegments.join(':').trim(); }); return dlrObj; } const parsed = parseDLR(dlrString); console.log(parsed.stat); // 输出 DELIVRD
这种方法代码更直白,适合团队里对正则不太熟悉的同学维护。
3. 基础分割优化(适合简单场景)
如果你确定DLR格式非常固定,text一定是最后一个字段,也可以优化基础分割方法,避免拆分text内容:
function parseDLRSimple(dlrStr) { const result = {}; // 找到最后一个"text:"的位置,把前面的内容和text分开 const textMarkerIndex = dlrStr.lastIndexOf('text:'); // 处理前面的键值对 const mainContent = dlrStr.slice(0, textMarkerIndex).trim(); mainContent.split(' ').forEach(item => { const [key, value] = item.split(':'); if (key && value) result[key] = value; }); // 单独提取text字段 result.text = dlrStr.slice(textMarkerIndex + 5).trim(); return result; }
这个方法代码最简单,但只适用于text是最后一个字段的固定格式,灵活性差一些。
总结下来,优先推荐正则表达式方案,它能应对所有标准DLR的格式变化,健壮性拉满。如果追求代码可读性,自定义函数也是不错的选择。
内容的提问来源于stack exchange,提问作者sinpleguy
相关产品推荐
相关产品推荐

