如何解析类SQL的JavaScript超集微语言,验证语法并提取规则信息?
解决方案
核心思路
既然不想重复开发JavaScript表达式解析器,直接利用JS原生能力处理表达式,先拆分解析规则中的关键字部分,再安全处理关键字后的表达式内容。
步骤1:解析规则字符串,提取关键字与对应内容
先拆分并清理规则文本(兼容单行/多行),匹配大写关键字并提取对应内容,同时做基础语法校验:
function parseRule(ruleStr) { // 拆分行并过滤空内容 const lines = ruleStr.split(/\r?\n/).map(line => line.trim()).filter(line => line); const rule = {}; for (const line of lines) { const match = line.match(/^([A-Z]+)\s+(.*)$/); if (!match) throw new Error(`无效规则行:${line}`); const [, keyword, content] = match; rule[keyword.toLowerCase()] = content; } // 校验必填关键字逻辑 if (!rule.set && !rule.remove) throw new Error("规则必须包含SET或REMOVE关键字"); if (rule.set && !rule.to) throw new Error("SET规则必须搭配TO关键字"); if (rule.remove && !rule.id) throw new Error("REMOVE规则必须搭配ID关键字"); return rule; }
步骤2:安全处理JavaScript表达式
用Function构造函数替代eval,避免全局污染,同时限制表达式可访问的变量范围:
// 安全执行表达式,仅允许传入指定上下文变量 function evaluateExpression(expr, context = {}) { // 先做危险内容校验 const dangerousKeywords = /eval|Function|new|window|globalThis/; if (dangerousKeywords.test(expr)) { throw new Error("表达式包含危险内容"); } try { const fn = new Function(...Object.keys(context), `return ${expr};`); return fn(...Object.values(context)); } catch (e) { throw new Error(`无效表达式:${expr},错误信息:${e.message}`); } }
步骤3:整合到系统规则函数
将解析结果和表达式处理后的数据,填充到addRuleToTheSystem函数:
function processRule(ruleStr, context) { const parsedRule = parseRule(ruleStr); // 处理各关键字对应的表达式 if (parsedRule.to) parsedRule.toValue = evaluateExpression(parsedRule.to, context); if (parsedRule.when) parsedRule.whenCondition = evaluateExpression(parsedRule.when, context); if (parsedRule.id) parsedRule.idValue = evaluateExpression(parsedRule.id, context); // 调用系统规则添加函数 if (parsedRule.set) { addRuleToTheSystem({ type: 'set', property: parsedRule.set, module: parsedRule.module, value: parsedRule.toValue, condition: parsedRule.whenCondition }); } else if (parsedRule.remove) { addRuleToTheSystem({ type: 'remove', property: parsedRule.remove, module: parsedRule.module, id: parsedRule.idValue }); } }
内容的提问来源于stack exchange,提问作者Astarno
相关产品推荐
相关产品推荐

