
本文介绍一种简洁、安全且可扩展的方式,将形如 "0...100 & [70...80, 0...100] & 30...50" 的结构化范围字符串,递归解析为合法 JavaScript 表达式并求值,从而高效判断数值是否满足嵌套逻辑条件。
本文介绍一种简洁、安全且可扩展的方式,将形如 `"0...100 & [70...80, 0...100] & 30...50"` 的结构化范围字符串,递归解析为合法 javascript 表达式并求值,从而高效判断数值是否满足嵌套逻辑条件。
在前端开发中,常需对用户输入的动态范围表达式进行校验(例如权限配置、表单验证或规则引擎)。原始 inRange 函数已支持基础逻辑(& 表示 AND、, 表示 OR、... 表示区间),但面对嵌套结构(如 [70...80, 0...100])时,手动递归解析括号层级易出错、可维护性差。更优解是语法转换 + 安全求值:将自定义语法映射为标准 JavaScript 布尔表达式,再通过 Function 构造器执行(注意:仅限可信上下文)。
✅ 核心思路:正则驱动的语法转换
不直接手写递归解析器,而是利用正则表达式分步替换,将领域特定语法(DSL)转为等价 JS 代码:
- [ → (,] → ):提升嵌套优先级,匹配 JS 运算符结合律;
- & → &&,, → ||:统一逻辑运算符;
- X...Y → X = X,...Y → num
⚠️ 关键细节:使用 (?
? 完整实现代码
const inRange = (num, str) => {
// 定义语法转换规则:[正则/字符串, 替换模板]
const substitutions = [
['&', ' && '], // AND 运算符
[/^(?= $1'], // "0..." → "num >= 0"
[/(\d+)\.\.\.(\d+)/g, '$1 = 0)
console.log(inRange(100, "...100")); // true (100 <h3>⚠️ 注意事项与最佳实践</h3>
- 安全性前提:new Function() 仅适用于完全可信的输入源(如配置文件、内部管理后台)。若 rngStr 来自用户输入,必须先做白名单校验(如仅允许数字、...、&、,、[、]、空格),或改用 AST 解析器(如 acorn)。
- 空格处理:替换中加入空格(如 ' ( ')可避免 &&( 等非法 JS 语法;生产环境建议额外调用 .replace(/\s+/g, ' ').trim() 规范空白。
- 错误反馈:封装 try/catch 提供清晰错误信息,便于调试非法表达式。
- 性能考量:对于高频调用场景,可缓存 Function 实例(基于 rngStr 哈希),避免重复编译。
? 总结
该方案以“语法即代码”思想,绕过复杂递归解析,用声明式正则完成 DSL 到 JS 的精准映射。它兼具简洁性(
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











