arekx / array-expression-engine
数组表达式引擎解析器
Requires
- php: >=7.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-13 23:02:44 UTC
README
这是一个数组表达式解析器,可以用于解析使用PHP数组中指定的配置进行配置的值。这些数组可以从任何地方加载,例如JSON字符串、PHP文件等。
这些表达式用于配置表达式解析引擎,该引擎通过数组表达式中的规则运行值以返回结果。
安装
在您的项目中运行 composer require arekx/array-expression-engine
。
用法
$isAStark = [ 'or', [ 'and', ['compare', ['get', 'first'], 'in', ['value', ['Arya', 'Sansa']]], ['compare', ['get', 'last'], '=', ['value', 'Stark']], ], ['regex', ['get', 'emblem'], '/stark/i'] ]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $values = [ ['first' => 'John', 'last' => 'Snow', 'emblem' => 'stark'], ['first' => 'Arya', 'last' => 'Stark', 'emblem' => 'stark'], ['first' => 'Sansa', 'last' => 'Stark', 'emblem' => 'stark'], ['first' => 'Joffrey', 'last' => 'Lannister', 'emblem' => 'lannister'] ]; foreach ($values as $value) { var_dump($evaluator->run($isAStark, $value)); } // Output: bool(true), bool(true), bool(true), bool(false)
运算符
摘要
以下运算符可用
AND 运算符
AND 运算符在 ArekX\ArrayExpression\Operators\AndOperator
类中定义,用于表示两个或多个表达式之间的 AND 操作,这些表达式可以是任何其他运算符,包括 AND 运算符。
示例
$nameMustBeTestAndAgeAbove2 = ['and', ['compare', ['get', 'name'], ['value', 'test']], ['compare', ['get', 'age'], '>', ['value', 2]]]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($nameMustBeTestAndAgeAbove2, ['name' => 'test', 'age' => 1]); // returns false
OR 运算符
OR 运算符在 ArekX\ArrayExpression\Operators\OrOperator
类中定义,用于表示两个或多个表达式之间的 OR 操作,这些表达式可以是任何其他运算符,包括 OR 运算符。
示例
$nameMustBeTestOrAgeAbove2 = ['or', ['compare', ['get', 'name'], ['value', 'test']], ['compare', ['get', 'age'], '>', ['value', 2]]]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($nameMustBeTestOrAgeAbove2, ['name' => 'test', 'age' => 1]); // returns true
XOR 运算符
XOR 运算符在 ArekX\ArrayExpression\Operators\XOrOperator
类中定义,用于表示两个或多个表达式之间的 XOR 操作,这些表达式可以是任何其他运算符,包括 XOR 运算符。
示例
$nameMustBeTestXOrAgeAbove2 = ['xor', ['compare', ['get', 'name'], ['value', 'test']], ['compare', ['get', 'age'], '>', ['value', 2]]]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($nameMustBeTestXOrAgeAbove2, ['name' => 'test', 'age' => 2]); // returns false
NOT 运算符
NOT 运算符在 ArekX\ArrayExpression\Operators\NotOperator
类中定义,用于表示 NOT 操作或对传递给它的表达式的取反。
示例
$expression = ['not', ['or', ['compare', ['get', 'name'], ['value', 'test']], ['compare', ['get', 'age'], '>', ['value', 2]]]]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['name' => 'test', 'age' => 5]); // returns false
BETWEEN 运算符
BETWEEN 运算符在 ArekX\ArrayExpression\Operators\BetweenOperator
类中定义,用于检查一个值是否在最小值和最大值之间。
示例
$expression = ['between', ['get', 'age'], ['value', 1], ['value', 20]]; // Check if age is >= 1 and <= 20 $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['age' => 5]); // returns true
COMPARE 运算符
比较两个表达式的比较运算符。它在 ArekX\ArrayExpression\Operators\CompareOperator
中定义。
比较运算符接受多种格式
短格式
['compare', <expressionA>, <expressionB>]
检查 <expressionA>
是否等于(严格)<expressionB>
关系格式
['compare', <expressionA>, '>=', <expressionB>]
检查 <expressionB>
是否大于或等于 <expressionB>
并返回 true
/false
支持的关系运算符
>
- 大于>=
- 大于或等于<
- 小于<=
- 小于或等于<>
- 不等于in
- 是值之一。例如['compare', <expressionA>, ['value', [1,2,10]]]
检查<expressionA>
是否为1
、2
或10
。
示例
$expression = ['compare', ['get', 'name'], ['value', 'test']]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['name' => 'test', 'age' => 5]); // returns true
REGEX 运算符
REGEX 运算符在 ArekX\ArrayExpression\Operators\RegexOperator
类中定义,用于检查一个值是否与特定的正则表达式模式匹配。
REGEX 运算符接受多种格式
字符串格式
['regex', <expression>, '/pattern/']
检查 <expression>
是否匹配特定模式。从 <expression>
返回的值必须是一个字符串。
表达式格式
['regex', <expression>, <expressionFormat>]
检查 <expression>
是否匹配由 <expressionFormat>
定义的特定模式。
从 <expression>
返回的值必须是一个字符串。
从 <expressionFormat>
返回的值必须是一个字符串。
示例
$expression = ['regex', ['get', 'name'], '/o/i']; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['name' => 'John']); // returns true
值运算符
值运算符在 ArekX\ArrayExpression\Operators\ValueOperator
类中定义,用于返回一个静态值。
示例
$expression = ['value', 50]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['name' => 'John']); // returns 50
获取运算符
获取运算符在 ArekX\ArrayExpression\Operators\GetOperator
类中定义,用于从键返回一个值。
示例
$expression = ['get', 'name']; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['name' => 'John']); // returns 'John'
连接运算符
连接操作符定义在 ArekX\ArrayExpression\Operators\ConcatOperator
类中,用于连接两个或多个字符串。它要求评估结果为字符串。
示例
$expression = ['concat', ['get', 'first'], ['value', ' '], ['get', 'last']]; $evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->run($expression, ['first' => 'John', 'last' => 'Snow']); // returns 'John Snow'
自定义操作符
您可以通过实现 Operator
接口并添加该操作符到您的 Evaluator
的 ExpressionParser
中来手动创建自己的自定义操作符。
我们将实现一个自定义操作符,将所有 cat
单词的实例转换为 dog
。
我们想要实现的操作符定义是:['dog', <expression>]
首先我们实现一个 Operator
类
use ArekX\ArrayExpression\Interfaces\ExpressionParser; use ArekX\ArrayExpression\Interfaces\Operator; use ArekX\ArrayExpression\Interfaces\ValueParser; class DogOperator implements Operator { /** @var ExpressionParser */ public $parser; /** @var string */ public $name; /** @var Operator */ public $subExpression; public function configure(array $config) { $this->name = $config[0]; $this->assertIsExpression($config[1]); // Assert that the value is an expression. $this->subExpression = $this->parser->parse($config[1]); } public function getName(): string { return $this->name; } public function setParser(ExpressionParser $parser) { $this->parser = $parser; } public function evaluate(ValueParser $value) { return str_ireplace('cat', 'dog', $this->subExpression->evaluate($value)); } }
创建此类后,我们需要将其添加到评估器的表达式解析器中,然后我们就可以设置了
$evaluator = \ArekX\ArrayExpression\Evaluator::create(); $evaluator->getExpressionParser()->setType('dog', DogOperator::class); $test = ['dog', ['get', 'sentence']]; $result = $evaluator->run($test, ['sentence' => 'Hello this is cat.']); // Returns: Hello this is dog.
测试
运行 composer test
来运行测试。