基于node-smpp的SMPP DLR报告stat字段高效解析方法问询
高效解析SMPP DLR响应的方案
嘿,很高兴你的node-smpp服务运行得这么顺畅!关于DLR响应的解析,单纯用split确实不是最健壮的选择——万一某个字段的值(比如text)包含空格,或者字段名本身带空格(像submit date、done date这种),拆分逻辑很容易出错。这里有几个更靠谱的实现方法:
方法一:正则表达式(推荐,原生且健壮)
DLR的格式本质是键值对序列,键可能是单单词或带空格的短语,值直到下一个键的起始位置结束。我们可以用正则精准匹配每个键值对:
const dlrResponse = 'id:355e917d-xxxx-xxxx-xxxx-xxxxxxxxxxxx sub:001 dlvrd:001 submit date:2012191607 done date:2012191607 stat:DELIVRD err:000 text:Tester'; // 正则说明: // (\w+(?:\s\w+)?) 匹配带空格的键(如submit date)或单单词键(如stat) // ([^:]+?) 匹配值,直到遇到下一个"空格+键+冒号"或字符串结尾 const dlrRegex = /(\w+(?:\s\w+)?):([^:]+?)(?=\s\w+(?:\s\w+)?:|$)/g; const parsedDLR = {}; let matchResult; while ((matchResult = dlrRegex.exec(dlrResponse)) !== null) { // 把带空格的键转成下划线命名(比如submit_date),方便后续调用 const key = matchResult[1].replace(/\s/g, '_'); parsedDLR[key] = matchResult[2].trim(); } // 直接获取stat字段 console.log(parsedDLR.stat); // 输出 DELIVRD
这个方案的优势:
- 自动处理带空格的字段名(比如
submit date) - 不会因为字段值包含空格而错位(比如
text:Hello World也能正确解析) - 原生实现,不需要额外依赖
方法二:手动遍历拆分(适合简单固定场景)
如果你的DLR格式非常固定,不会出现值带空格的情况,也可以优化split的用法,但要注意处理带空格的键:
const dlrParts = dlrResponse.split(' '); const parsedDLR = {}; for (let i = 0; i < dlrParts.length; i++) { const [keyPart, ...valueParts] = dlrParts[i].split(':'); // 判断是否是带空格的键(比如submit date) if (keyPart === 'submit' || keyPart === 'done') { const fullKey = `${keyPart} ${dlrParts[i+1].split(':')[0]}`; const value = dlrParts[i+1].split(':')[1]; parsedDLR[fullKey.replace(/\s/g, '_')] = value; i++; // 跳过下一个元素,因为已经处理了 } else { parsedDLR[keyPart] = valueParts.join(':'); } }
不过这个方法灵活性差,一旦DLR格式有变化(比如新增带空格的字段)就需要修改代码,不如正则方案通用。
为什么不推荐单纯的split拆分?
比如如果你的DLR里text字段的值是Hello World,用split(' ')会得到['text:Hello', 'World'],这时候后续的键值对都会错位,导致你无法正确获取stat字段。正则方案从根本上避免了这个问题,因为它是基于下一个键的起始位置来分割值的,而不是单纯按空格拆分。
内容的提问来源于stack exchange,提问作者sinpleguy
相关产品推荐
相关产品推荐

