Giter Site home page Giter Site logo

texpr's Introduction

TExpr

Build Status Coverage status

Go语言布尔及数值运算表达式解析器

Java语言版本

布尔表达式:

$country in ['cn', 'us', 'jp'] && $length > 100
$host == 'cs.qa.com' && 'Webkit' not in $ua

数值运算表达式:

( 1 ^ 5) + (2 << 3)
4 | 3 + 3

Example

package main

import (
	"fmt"
	"log"

	"github.com/aliyun/texpr"
)

type context map[string]interface{}

func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}

func main() {
	m := context {
		"$value" : 15.0,
	}
	expr := texpr.MustCompile("$value - 10")
	v, err := expr.Eval(m)
	if err != nil {
		log.Fatalf("expression err, %s", err)
	}
	fmt.Println(v) // 5
}

表达式语法

标量变量

类型 范例 说明
字符串 'hello' , "world" 字符串可以用单引号或双引号
整数 1,3,64
浮点数 1.1, 3.14
布尔值 true/false
变量 $name, @meta 变量名必须用$或@作为前缀.
数组 ["hello", "world"] 数组元素的类型可以是上面5种类型中的一种

数值计算

操作符 描述 例子
+ 1+1=2
- 2-1=1
* 2*2=4
/ 2/2=1
% 取余 5/2=1
& 位与 33&44=34
| 位或 33|44=45
^ 异或 33|44=13
<< 左位移 1 << 3 = 8
>> 右位移 16 >> 3 = 2

布尔计算

关系运算符

操作符 描述 例子
== 两值相等 A==B
> 左值大于右值 A>B
< 右值大于左值 A<B
>= 左值大于等于右值 A>=B
<= 右值大于等于左值 A<=B

左值和右值必须为同类型

逻辑运算符

操作符 描述 例子
&& 称为逻辑与运算符。当且仅当两个操作数都为真,条件才为真。 A && B
|| 称为逻辑或操作符。如果任何两个操作数任何一个为真,条件为真。 A || B
not 称为逻辑非运算符。用来反转操作数的逻辑状态。如果条件为true,则逻辑非运算符将得到false。 not(A && B)

包含表达式

操作符 描述 例子
in 判断左值是否被包含在右值中,右值为数组类型 A in [A, B, C, D]
in 判断左值是否被包含在右值中,左值右值都是字符串或字符串类型变量 A in B

example

$name in ['John', 'Mary', "Jackson"]
'world' in 'hello world'

正则匹配

操作符 描述 例子
=~ 判断左值是匹配右值,右值是正则表达式 'world' =~ /.+orl.+/

正则表达式首尾需要用'/'包含

IS 判断

操作符 描述 例子
is 判断左值是否是右值代表的类型 A is empty
is not 判断左值是否不是右值代表的类型 A is not null

支持的类型如下

名称 描述 例子
string 字符串 A is string
integer 整数 A is integer
float 浮点数 A is float
boolean 布尔值 A is boolean && not A
host 主机名 A is host
ip4 ipv4地址 A is ip4
empty null、空字符、空数组 A is not empty
null null A is not null

范例

$name is string
$nil is null
'192.168.1.1' is ip4

函数运算

表达式函数

当前版本内置了一个函数'eval', 用来解析运算变量中的表达式, 范例:

// $expr = "$left + $right"
type context map[string]interface{}
func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}


m := context {
		"$left" : 2.0,
		"$right" : 3.0,
		"$ex" : "$left + $right"
}

expr, err := t.Compile("eval($ex)")

v, _ := expr.Eval(m)
// v == 5.0

自定义函数

可以在程序中自定义扩展函数, 只需要两个步骤

  1. 定义一个结构体, 实现Function接口
  2. 定义一个结构体变量并注册.

下面是自定义has_prefix函数的范例


type HasPrefixFunc struct {
	Function
}

func (f *HasPrefixFunc) Name() string {
	return "has_prefix"
}

func (f *HasPrefixFunc) Execute(vg ValueGetter, params []interface{}) (interface{}, error) {
	if len(params) != 2 {
		return nil, fmt.Errorf(`HasPrefixFunc() takes exactly 2 argument (" + %d + " given)`, len(params))
	}
	return strings.HasPrefix(params[0].(string), params[1].(string)), nil
}

func main() {
  RegisterFunc(&HasPrefixFunc{})
	...
}

Development

简单表达式计算

import (
	"fmt"
	"log"
	"os"

	t "github.com/aliyun/texpr"
)

func main() {
    input := "99 in "33 > 22 && 22 > 11"
	expr, err := t.Compile(input)

	if err != nil {
		log.Fatalf("expression err, %s", os.Args[1])
	}
	v, err := expr.Eval(nil)
	fmt.Println(v)
}

带有变量的表达式计算

表达式中可以带有变量,表达式中的变量必须以'$'或者'@'开头,如:

// 定义一个类型, 实现Get(string)interface{} 接口
type context map[string]interface{}
func (vg context) Get(name string) interface{} {
	v, ok := vg[name]
	if ok {
		return v
	}
	return nil
}

expr, err := t.Compile("($value - 10) / @meta")

m := context {
		"$value" : 15.0,
		"@meta" : 9.0,
}

v, err := expr.Eval(m)
if err != nil {
log.Fatalf("expression err, %s", err)
}

其中 expr.Eval() 的参数m,必须实现下面的interface

type ValueGetter interface {
	Get(name string) interface{}
}

在执行时,解释器会调用参数的Get方法取得表达式中变量的值,详细实现可以参考范例 test/variable/main.go

texpr's People

Contributors

alibaba-oss avatar rockis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.