@firehammer/jexl

中文文档
1.3.0发布于 2023/10/24MITCommonJS近 30 天下载 3969

Javascript 表达式语言: 强大的上下文表达式解析器和评价器

中文使用文档
文档目录22 节
  1. 快开始
  2. 来玩吧
  3. 安装
  4. Async vs Sync: 要使用哪个
  5. 所有细节
  6. 一元运算符
  7. 二进制运算符
  8. 比较
  9. 三级操作员
  10. 本地类型
  11. 组
  12. 标识符
  13. 收款
  14. 变换
  15. 职能
  16. A. 背景情况
  17. API 密码
  18. 胶片
  19. 表达式
  20. 其他执行情况
  21. 许可证
  22. 贷项

胶片

Javascript 表达式语言: 强大的上下文表达式解析器和评价器

这是从最初的作品 由 汤姆·弗罗斯特 应付 最初的存放处在此时有两年缺乏维护 叉来.

其他工作 切坦帕迪亚 用于改划 已输入到字符串的编译表达式.

快开始

与承诺或同步使用:

const context = {
  name: { first: 'Sterling', last: 'Archer' },
  assoc: [
    { first: 'Lana', last: 'Kane' },
    { first: 'Cyril', last: 'Figgis' },
    { first: 'Pam', last: 'Poovey' }
  ],
  age: 36
}

// Filter an array asynchronously...
await const res = jexl.eval('assoc[.first == "Lana"].last', context)
console.log(res) // Output: Kane

// Or synchronously!
console.log(jexl.evalSync('assoc[.first == "Lana"].last')) // Output: Kane

// Do math
await jexl.eval('age * (3 - 1)', context)
// 72

// Concatenate
await jexl.eval('name.first + " " + name["la" + "st"]', context)
// "Sterling Archer"

// Compound
await jexl.eval(
  'assoc[.last == "Figgis"].first == "Cyril" && assoc[.last == "Poovey"].first == "Pam"',
  context
)
// true

// Use array indexes
await jexl.eval('assoc[1]', context)
// { first: 'Cyril', last: 'Figgis' }

// Use conditional logic
await jexl.eval('age > 62 ? "retired" : "working"', context)
// "working"

// Transform
jexl.addTransform('upper', (val) => val.toUpperCase())
await jexl.eval('"duchess"|upper + " " + name.last|upper', context)
// "DUCHESS ARCHER"

// Transform asynchronously, with arguments
jexl.addTransform('getStat', async (val, stat) => dbSelectByLastName(val, stat))
try {
  const res = await jexl.eval('name.last|getStat("weight")', context)
  console.log(res) // Output: 184
} catch (e) {
  console.log('Database Error', e.stack)
}

// Functions too, sync or async, args or no args
jexl.addFunction('getOldestAgent', () => db.getOldestAgent())
await jexl.eval('age == getOldestAgent().age', context)
// false

// Add your own (a)synchronous operators
// Here's a case-insensitive string equality
jexl.addBinaryOp(
  '_=',
  20,
  (left, right) => left.toLowerCase() === right.toLowerCase()
)
await jexl.eval('"Guest" _= "gUeSt"')
// true

// Compile your expression once, evaluate many times!
const { expr } = jexl
const danger = expr`"Danger " + place` // Also: jexl.compile('"Danger " + place')
danger.evalSync({ place: 'zone' }) // Danger zone
danger.evalSync({ place: 'ZONE!!!' }) // Danger ZONE!!! (Doesn't recompile the expression!)

来玩吧

安装

Jexl在后端工作,如果用Parcel或Webpack这样的捆绑器捆绑,则在前端工作.

从 npm 安装 :

npm install jexl --save

线条 :

yarn add jexl

并使用它:

const jexl = require('jexl')

Async vs Sync: 要使用哪个

表现差异不大 eval 财务报告和审定财务报表 evalSync功能 区别是,如果 eval 使用时,Jexl可以使用同步操作器进行定制, 变换,甚至等待上下文中的未兑现的许诺 管理或处理程序员. evalSync 消除这些优势, 将表达式暴露在原始的许诺对象中,如果由于一个 自定义转换或操作员。 但是,如果你的应用 不需要同步方法, 页:1 evalSync API可以比较简单使用.

所有细节

一元运算符

运行符号
忽略来啊!

二进制运算符

运行符号
添加, 控制器+ 键
减法- 说吧
乘数* 联合国
除号编号 :
差额和下限/ 请检查url=值 (帮助)
模块百分比(%)
权力^
逻辑和&&
逻辑 OR||

比较

比较符号
平等==
不相等=
超过> 翻译:
大于或等于>=
少于<
少于或等于<=
数组或字符串中的元素内

关于 in

这个 in 操作符可用于检查子字符串 : "Cad" in "Ron Cadillac",可用于检查数组元素: "coarse" in ['fine', 'medium', 'coarse']然而 == 使用运算符 用于搜索阵列的幕后屏幕,所以不应与下列阵列一起使用: 对象。 以下表达式返回虚假 : {a: 'b'} in [{a: 'b'}]。 。 。 .

三级操作员

有条件的表达式检查以查看第一段是否评价为真 数值。 如果是,则对随后的部分进行评价。 否则,候补 没错 如果随后的段落缺失, 将使用测试结果本身 换句话说.

表达式结果
""?"出":"E"空
""出"作"出""出""出""出""出""出""出""出""出""出""出""出""出""出""出""出""出""出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出"出""出"出"出"出"出"出"出"出"对
{代理:"Archer"}.代理:"坎"阿彻

本地类型

类型实例
布尔true, (中文(简体) ), false
字符串"你好,"用户","你好!"
数字6-7.2, 5, -3.14159 (中文(简体) )
对象- 你好,"世界!" ) 。
阵列["你好","世界!"

组

父母的工作就像你期望他们:

表达式结果
(83+1) / 2 (中文(简体) )第42条
1 < 3 > (4 > 2 > 2 > 4)真实

标识符

只需输入上下文对象的名称即可访问变量 。 对象可以 用点标记或用括号来显示动态 属性名称.

实例上下文:

{
  name: {
    first: "Malory",
    last: "Archer"
  },
  exes: [
    "Nikolai Jakov",
    "Len Trexler",
    "Burt Reynolds"
  ],
  lastEx: 2
}
表达式结果
名称。 第一个马洛里
名称 ['la' +'st']阿彻
前任 [2]伯特·雷诺兹
exes [最后Ex - 1] (中文(简体) )伦·特雷克勒

收款

集合或对象阵列可以通过包含过滤器过滤 括号中的表达式。 每个收藏的属性可以通过 以主点前缀。 结果是一系列对象 过滤表达式产生了真实值.

实例上下文:

{
    employees: [
        {first: 'Sterling', last: 'Archer', age: 36},
        {first: 'Malory', last: 'Archer', age: 75},
        {first: 'Lana', last: 'Kane', age: 33},
        {first: 'Cyril', last: 'Figgis', age: 45},
        {first: 'Cheryl', last: 'Tunt', age: 28}
    ],
    retireAge: 62
}
表达式结果
员工[. 第一 ==="斯特林"[{第一:'Sterling',最后:'Archer',年龄:36}]
员工[. last = "Tu" + "nt"]. 第一个谢丽尔
雇员[.岁 30.岁 < 40][{第一:''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
雇员[.年龄 30 .年龄 < 40][.年龄 < 35][{第一:'Lana',最后:'Kane',年龄:33}]
雇员[.岁 马洛里

变换

Jexl的力量在于同步或同步地转换数据. 变换函数需要一个或多个参数 : 改变的价值, 然后在表达中传递给它的任何东西。 他们必须回来 或与被转变的 数值。 加入它们 jexl.addTransform(name, function)。 。 。 .

jexl.addTransform("split", (val, char) => val.split(char));
jexl.addTransform("lower", (val) => val.toLowerCase());
表达式结果
"Pam Poovey" =============================================================oo
"密码""==""分"("="+")["密码","客人"]

高级变换

使用 Transforms, Jexl 可以支持像嵌入式那样的额外字符串格式 JSON,YAML,XML,还有更多。 接下来,在.. xml2json 图像 模块,允许 XML 为 穿行像普通的活字标本一样容易:

const xml2json = require("xml2json");

jexl.addTransform("xml", (val) => xml2json.toJson(val, { object: true }));

const context = {
  xmlDoc: `
    <Employees>
      <Employee>
        <FirstName>Cheryl</FirstName>
        <LastName>Tunt</LastName>
      </Employee>
      <Employee>
        <FirstName>Cyril</FirstName>
        <LastName>Figgis</LastName>
      </Employee>
    </Employees>`
};

var expr = 'xmlDoc|xml.Employees.Employee[.LastName == "Figgis"].FirstName';

jexl.eval(expr, context).then(console.log); // Output: Cyril

职能

虽然变形是将一个值变为另一个值的首选方式, Jexl还允许定义顶级表达功能. 使用这些 提供对不需要输入或需要输入的函数的访问 多种同样重要的投入。 它们可以添加到 jexl.addFunction(name, function)。与变换一样,函数可以返回 a 值,或解决由此产生的值的许诺.

jexl.addFunction("min", Math.min);
jexl.addFunction("expensiveQuery", async () => db.runExpensiveQuery());
表达式结果
分钟( 4, 2, 19)2个
qQ 昂贵查询( )查询仅在需要时运行

A. 背景情况

可变上下文是可访问的直截了当的 Javascript 对象 在表达式中,但他们有一个隐藏的特征:他们可以包含一个承诺 对象,当使用该属性时, Jexl 将等待承诺 解决并使用这个价值!

API 密码

胶片

jexl (英语). 胶片

提及了Jexl构造器. 保留单独的 Jexl 实例 每一个都保持了自己的一套变换, 简单地用 new jexl.Jexl()。 。 。 .

jexl.add BinaryOp (中文(简体) ){字符串} 运算符, (中文(简体) ), {数}优先, (中文(简体) ), {函数} fn, (中文(简体) ), {boolean} [手动Eval](中文(简体) )

在 Jexl 实例中添加二进制运算符。 二进制运算符是 考虑其左右的数值,如"+"或"==",顺序 用来计算结果。 优先级决定了操作者在 行动顺序(请参考 lib/grammar.js 以查看 现有运算符)。 提供的职能将有两个理由: 左值和右值。 它应返回所产生的价值, 或承诺,解决由此产生的价值.

若为 manualEval 是真的,那个 left 财务报告和审定财务报表 right 参数将被包裹在 带有 eval 函数。 通话 left.eval() 或者说 right.eval() 将 回到一个承诺 解决操作的实际价值。 这对 有条件地评价操作,以及如何 && 财务报告和审定财务报表 || 工作时.

jexl.addunaryOp (英语:{字符串} 运算符, (中文(简体) ), {函数} fn(中文(简体) )

在 Jexl 实例中添加一个未使用的运算符。 单人操作员就是 仅考虑其右侧的值,如"!",以便计算 结果。 给定的函数将有一个参数: 接线员说得对 它应返回所产生的价值或承诺 这决定了由此产生的价值.

jexl.add 函数 (){字符串}名称, [功能] func )

向 Jexl 实例添加表达式函数。 见 职能 关于表达函数结构的信息.

jexl.add 函数 ()地图(中文(简体) )

从提供的函数名称地图中添加多个函数到表达式 函数.

jexl.add 变形( T){字符串}名称, (中文(简体) ), {函数} 转换(中文(简体) )

在此 Jexl 实例中添加变换函数 。 见 变换 关于变换功能结构的信息.

jexl.add 变形符 ()地图(中文(简体) )

从所提供的变形名地图中添加多个变形符以进行变形 函数.

jexl.compile (英语:{字符串} 表达式(中文(简体) )

围绕给定的 Jexl 表达式字符串构建表达式对象. 表达式对象只允许编译一次 Jexl 表达式,但 多次评估。 参见下面的表达式 API. 请注意,唯一的 此函数与 jexl.createExpression 就是这个 函数将立即编译表达式,并扔出任何错误 与无效表达式语法相关.

jexl.create Express () (帮助){字符串} 表达式(中文(简体) )

围绕给定的 Jexl 表达式字符串构建表达式对象. 表达式对象只允许编译一次 Jexl 表达式,但 多次评估。 参见下面的表达式 API.

jexl.get 变形( T){字符串}名称(中文(简体) )

回返 {function|undefined}。 。 。 . 获得先前设定的变换功能, 或者说 undefined 如果该名称不存在函数.

jexl. eval (英语:{字符串} 表达式, (中文(简体) ), [文(中文(简体) )

回返 {Promise<*>}。 。 。 . 评估表达式。 上下文映射是可选的.

jexl. evallSync (英语:{字符串} 表达式, (中文(简体) ), [文(中文(简体) )

回返 {*}。 。 。 . 评估表达式并返回结果。 上下文地图 是可选的.

jexl.expr: (英语) 标记模板文字

方便点的合成糖 jexl.createExpression

const someNumber = 10;
const expression = jexl.expr`5 + ${someNumber}`;
console.log(expression.evalSync()); // 15

请注意: expr 将保持约束 与其关联的 Jexl 实例,即使它是 断章取义:

const { expr } = jexl;
jexl.addTransform("double", (val) => val * 2);
const expression = expr`2|double`;
console.log(expression.evalSync()); // 4

jexl.removeOp (英语:{字符串} 运算符(中文(简体) )

从 Jexl 实例中删除二进制或非二进制运算符。 例如,“^”可以 被通过来消除操作者的"力量".

表达式

表达式对象通过 jexl.createExpression, (中文(简体) ), jexl.compile,或 jexl.expr,并且是一种确保jexl表达式只编译的方便方法 一次,即使被多次评价.

表达式. 编译 ()

自行回归 {Expression}。 。 。 . 强迫表达式编译, 即使它 之前被编译。 请注意, 每个编译会随最新的语法一起发生 并且从相关的 Jexl 实例中转换.

表达式. eval ()[文(中文(简体) )

回返 {Promise<*>}。 。 。 . 评估表达式。 上下文图是 选项.

表达式. evallSync ()[文(中文(简体) )

回返 {*}。 。 。 . 评估表达式并返回结果。 二. 背景情况 地图是可选的.

其他执行情况

PyJEXL 密码 - 一个基于Python的JEXL解析器和评估器.

许可证

Jexl持有麻省理工学院许可证。 请看 LICENSE.txt 详细情况.

贷项

创建于 汤姆·肖弗 2015年捐款情况 这些伟大的人。 。 。 .

Jexl 最初创建于 技术咨询 在纳什维尔,TN.

驾驶员: 火锤解决方案的Aaron Stephens 在2023年时.

版本与发布记录

@firehammer/jexl 共发布 5 个版本,首次发布于 2023/02/18;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.3.0latest2023/10/243 年前
1.2.02023/04/063 年前
1.1.12023/03/223 年前
1.1.02023/03/093 年前
1.0.02023/02/183 年前

关于 @firehammer/jexl 的常见问题

@firehammer/jexl 是什么?

Javascript 表达式语言: 强大的上下文表达式解析器和评价器

如何安装 @firehammer/jexl?

在项目目录运行 npm install @firehammer/jexl,或使用 pnpm add / yarn add / bun add。

@firehammer/jexl 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/firehammer__jexl 是否存在。

@firehammer/jexl 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@firehammer/jexl 可以商用吗?

@firehammer/jexl 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@firehammer/jexl 的下载量有多少?

根据 npm 官方下载统计,@firehammer/jexl 在 2026/10/15 – 2026/11/13 这 30 天内被下载 3,969 次,日均约 132 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@firehammer/jexl 还在维护吗?

最新版本 1.3.0 发布于 2023/10/24(3 年前);至今共发布 5 个版本,其中过去 12 个月发布了 0 个;首次发布于 2023/02/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。