Node.js 类CLI服务输入解析:如何拆分命令与参数并调用对应函数
实现方案
解决三个核心需求:正确解析带引号的输入片段、自动匹配嵌套命令函数、将入参转换为键值对对象,同时移除原代码中不安全的eval逻辑。
完整实现代码
function command(inputStr, usable) { // 第一步:将输入字符串解析为token数组,正确处理带引号的内容 const tokenReg = /[^"\s]+|"([^"]*)"/g; const tokens = []; let match; while ((match = tokenReg.exec(inputStr)) !== null) { tokens.push(match[1] ?? match[0]); } // 第二步:匹配可用命令,拆分命令主体与参数段 let currentPath = usable; let commandEndIndex = -1; for (let i = 0; i < tokens.length; i++) { const segment = tokens[i]; if (typeof currentPath[segment] === 'function') { // 匹配到执行函数,记录命令段结束位置 currentPath = currentPath[segment]; commandEndIndex = i; break; } else if (currentPath[segment] && typeof currentPath[segment] === 'object') { // 嵌套命令层级,继续向下匹配 currentPath = currentPath[segment]; } else { // 匹配不到命令路径,直接返回false return false; } } if (commandEndIndex === -1) return false; // 第三步:将剩余token解析为参数对象 const params = {}; const paramTokens = tokens.slice(commandEndIndex + 1); const paramReg = /^"?([^":]+)"?:(.*)$/; for (const paramStr of paramTokens) { const paramMatch = paramStr.match(paramReg); if (!paramMatch) continue; const key = paramMatch[1]; // 去除value两端可能的引号 const value = paramMatch[2].replace(/^"|"$/g, ''); params[key] = value; } // 执行对应命令函数,传入参数对象 return currentPath(params); }
使用示例
// 定义可用命令集合 const usable = { do: { say: (params) => { console.log('收到say命令参数:', params); // 业务逻辑写在此处 return true; } } }; // 测试样例(字符串直接从WebSocket接收即可,无需处理process.argv) const input = 'do say user:Yimmee msg:"well hello" "something random":yes'; command(input, usable); // 输出:收到say命令参数:{ user: 'Yimmee', msg: 'well hello', 'something random': 'yes' }
逻辑说明
- 自动适配任意层级的嵌套命令,无需修改代码即可支持
a b c这类多段命令的匹配 - 完全兼容带引号的key、value参数格式,不会错误拆分引号内的空格
- 移除了
eval逻辑,避免恶意输入导致的安全风险,适配WebSocket场景的不可信输入 - 未匹配到对应命令时返回
false,和原有代码的异常处理逻辑保持兼容
内容的提问来源于stack exchange,提问作者user14591266
相关产品推荐
相关产品推荐

