胶片
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 游戏场 - 一个互动的Jexl沙盒 由克里斯蒂安·佐塞尔 @czosel (英语)。 。 。 .
- 运行 Kit 上的 Jexl - Jexl预装了JS沙盒 特别感谢迈克·昆宁 @ cunneen (英语)。 。 。 .
安装
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年时.