เอกสารอ้างอิง API ของ Common Expression Language (CEL)

เอกสารนี้เป็นข้อมูลอ้างอิงเอกสาร API แบบรวมสำหรับ Common Expression Language (CEL) โดยจะแสดงรายการมาโคร โอเปอเรเตอร์ และฟังก์ชันมาตรฐานทั้งหมด พร้อมระบุลายเซ็น ลักษณะการทำงาน และสถานะการรองรับในสแต็ก CEL อย่างเป็นทางการ

ดูรายละเอียดเพิ่มเติมเกี่ยวกับลักษณะการทำงานและข้อกำหนดของภาษาได้ที่คำจำกัดความของภาษา CEL

เวอร์ชัน Stack

เอกสารอ้างอิงนี้อิงตามสแต็ก CEL เวอร์ชันต่อไปนี้

  • CEL Go: v0.29.2 (และใหม่กว่า)
  • CEL C++: v0.15.0
  • CEL Java: v0.13.1
  • CEL Python: v0.1.3
  • CEL C: ภาพรวมการพัฒนา (ยังไม่ได้เผยแพร่)

มิเรอร์ GitHub

การใช้งาน CEL อย่างเป็นทางการจะมิเรอร์ใน GitHub ภายใต้cel-expr องค์กร


1. มาโครหลัก

มาโครเหล่านี้เป็นมาโครในตัวที่จะขยายในเวลาคอมไพล์

มาโคร คำอธิบาย Go C++ Java Python C
has(container.field) ทดสอบว่ามีฟิลด์ในข้อความหรือคีย์ในแผนที่หรือไม่

ลายเซ็น:
has(container.field) -> bool

ตัวอย่าง:
has(request.auth.claims.email)
list.all(var, predicate) ทดสอบว่าองค์ประกอบทั้งหมดในลิสต์เป็นไปตามเพรดิเคตหรือไม่

ลายเซ็น:
list.all(var, predicate) -> bool

ตัวอย่าง:
[1, 2, 3].all(x, x > 0) // true
¹
list.exists(var, predicate) ทดสอบว่าองค์ประกอบอย่างน้อย 1 รายการในลิสต์ตรงตามเพรดิเคตหรือไม่

ลายเซ็น:
list.exists(var, predicate) -> bool

ตัวอย่าง:
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) ทดสอบว่ามีองค์ประกอบเพียง 1 รายการในรายการที่ตรงตามเพรดิเคตหรือไม่

ลายเซ็น:
list.exists_one(var, predicate) -> bool

ตัวอย่าง:
[1, 2, 3].exists_one(x, x == 2) // true
¹
list.filter(var, predicate) กรององค์ประกอบของรายการตามเพรดิเคต

ลายเซ็น:
list.filter(var, predicate) -> list

ตัวอย่าง:
[1, 2, 3].filter(x, x > 1) // [2, 3]
¹
list.map(var, transform) เปลี่ยนรูปแบบแต่ละองค์ประกอบของลิสต์โดยใช้นิพจน์

ลายเซ็น:
list.map(var, transform) -> list

ตัวอย่าง:
[1, 2, 3].map(x, x * 2) // [2, 4, 6]
¹
list.map(var, filter, transform) เปลี่ยนรูปแบบองค์ประกอบของรายการที่ตรงตามตัวกรอง

ลายเซ็น:
list.map(var, filter, transform) -> list

ตัวอย่าง:
[1, 2, 3].map(x, x > 1, x * 2) // [4, 6]
¹

¹ รองรับในรันไทม์ C เนื่องจากคอมไพเลอร์โฮสต์จะขยายแมโครเป็นความเข้าใจในระหว่างการคอมไพล์


2. โอเปอเรเตอร์หลัก

โอเปอเรเตอร์ คำอธิบาย Go C++ Java Python C
เลขคณิต (+, -, *, /, %) การดำเนินการทางคณิตศาสตร์มาตรฐาน การปฏิเสธ (-x) และเอกลักษณ์ (+x) การต่อรายการ (list + list) รองรับใน Go, C++, Java และ Python

ลายเซ็น:
T + T -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

ตัวอย่าง:
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
การเปรียบเทียบ (==, !=, <, <=, >, >=) การเปรียบเทียบมาตรฐาน การเปรียบเทียบตัวเลขเป็นแบบไม่เหมือนกัน (เช่น 1 == 1.0)

ลายเซ็น:
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

ตัวอย่าง:
x < 42.0
1 == 1.0 // true
เชิงตรรกะ (!, &&, ||, ? :) Logical NOT, AND, OR และ Ternary Conditional และ/หรือใช้การประเมินแบบลัด

ลายเซ็น:
!bool -> bool
bool && bool -> bool
bool || bool -> bool
bool ? T : T -> T

ตัวอย่าง:
x > 0 ? "positive" : "non-positive"
การจัดทำดัชนี ([]) เข้าถึงองค์ประกอบของลิสต์ตามดัชนี หรือค้นหาคีย์ในแมป

ลายเซ็น:
list[int] -> T
map[K] -> V

ตัวอย่าง:
tags[0]
users['john']
การเป็นสมาชิก (in) ตรวจสอบว่าองค์ประกอบอยู่ในลิสต์หรือคีย์อยู่ในแมป

ลายเซ็น:
T in list -> bool
K in map -> bool

ตัวอย่าง:
'admin' in roles

² รันไทม์ C ไม่รองรับการเชื่อมโยงรายการ (list + list) แม้ว่าจะรองรับตัวดำเนินการทางคณิตศาสตร์อื่นๆ


3. ฟังก์ชันหลัก

ฟังก์ชันทั่วไปและฟังก์ชันสตริง

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
size แสดงขนาดของสตริง (อักขระ) ไบต์ รายการ หรือแมป

ลายเซ็น:
size(T) -> int (โดยที่ T คือ string, bytes, list หรือ map)<br /><br />**Examples:**<br />size("hello") // 5`
contains แสดงว่าสตริงมีสตริงย่อยหรือไม่

ลายเซ็น:
string.contains(string) -> bool

ตัวอย่าง:
"hello".contains("ell") // true
startsWith แสดงว่าสตริงขึ้นต้นด้วยคำนำหน้าหรือไม่

ลายเซ็น:
string.startsWith(string) -> bool

ตัวอย่าง:
"hello".startsWith("he") // true
endsWith แสดงว่าสตริงลงท้ายด้วยคำต่อท้ายหรือไม่

ลายเซ็น:
string.endsWith(string) -> bool

ตัวอย่าง:
"hello".endsWith("lo") // true
matches แสดงผลว่าสตริงตรงกับนิพจน์ทั่วไป RE2 หรือไม่

ลายเซ็น:
string.matches(string) -> bool

ตัวอย่าง:
"123".matches(r"^\d+$") // true

ฟังก์ชันตัวเลือกวันที่และเวลา

ฟังก์ชันเหล่านี้จะดึงคอมโพเนนต์จาก google.protobuf.Timestamp หรือ google.protobuf.Duration

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
getFullYear แสดงปีเป็นตัวเลข 4 หลัก

รูปแบบ
timestamp.getFullYear([tz]) -> int

ตัวอย่าง
timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026
getMonth แสดงเดือน (0-11)

ลายเซ็น:
timestamp.getMonth([tz]) -> int

ตัวอย่าง:
timestamp("2026-07-23T00:00:00Z").getMonth() // 6
getDayOfMonth แสดงผลวันของเดือน (1-31)

รูปแบบ
timestamp.getDayOfMonth([tz]) -> int

ตัวอย่าง
timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23
getDayOfWeek แสดงวันในสัปดาห์ (0 = วันอาทิตย์)

ลายเซ็น:
timestamp.getDayOfWeek([tz]) -> int

ตัวอย่าง:
timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4
getDayOfYear แสดงวันในปี (0-365)

รูปแบบ
timestamp.getDayOfYear([tz]) -> int

ตัวอย่าง
timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203
getHours แสดงผลชั่วโมง (0-23)

ลายเซ็น:
timestamp.getHours([tz]) -> int
duration.getHours() -> int

ตัวอย่าง:
duration("1h30m").getHours() // 1
getMinutes แสดงผลนาที (0-59)

ลายเซ็น:
timestamp.getMinutes([tz]) -> int
duration.getMinutes() -> int

ตัวอย่าง:
duration("1h30m").getMinutes() // 30
getSeconds แสดงผลวินาที (0-59)

รูปแบบลายเซ็น:
timestamp.getSeconds([tz]) -> int
duration.getSeconds() -> int

ตัวอย่าง:
duration("1h30m45s").getSeconds() // 45
getMilliseconds แสดงผลมิลลิวินาที (0-999)

ลายเซ็น:
timestamp.getMilliseconds([tz]) -> int
duration.getMilliseconds() -> int

ตัวอย่าง:
duration("1.5s").getMilliseconds() // 500

การแปลงประเภท

ประเภทเป้าหมาย คำอธิบาย Go C++ Java Python C
bool แปลงเป็นบูลีน

ลายเซ็น:
bool(bool) -> bool
bool(string) -> bool

ตัวอย่าง:
bool("true") // true
bytes แปลงเป็นไบต์

ลายเซ็น:
bytes(bytes) -> bytes
bytes(string) -> bytes

ตัวอย่าง:
bytes("hello") // b"hello"
double แปลงเป็นจำนวนทศนิยมแบบความแม่นยำสองเท่า

ลายเซ็น:
double(double) -> double
double(int) -> double
double(uint) -> double
double(string) -> double

ตัวอย่าง:
double(1) // 1.0
duration แปลงเป็นระยะเวลา

ลายเซ็น:
duration(duration) -> duration
duration(string) -> duration

ตัวอย่าง:
duration("1.5s") // 1.5s duration
int แปลงเป็นจำนวนเต็มแบบมีเครื่องหมาย 64 บิต

ลายเซ็น:
int(int) -> int
int(uint) -> int
int(double) -> int (ปัดเป็น 0)
int(string) -> int
int(timestamp) -> int (วินาทีตั้งแต่ Epoch)

ตัวอย่าง:
int(1.5) // 1
string แปลงเป็นสตริง

ลายเซ็น:
string(T) -> string (รองรับ bool, int, uint, double, bytes, timestamp, duration)<br /><br />**Examples:**<br />string(1.5) // "1.5"`
timestamp แปลงเป็น Timestamp

รูปแบบ:
timestamp(timestamp) -> timestamp
timestamp(string) -> timestamp (RFC3339)

ตัวอย่าง:
timestamp("2026-07-23T00:00:00Z")
uint แปลงเป็นจำนวนเต็มแบบไม่มีเครื่องหมาย 64 บิต

ลายเซ็น:
uint(uint) -> uint
uint(int) -> uint
uint(double) -> uint
uint(string) -> uint

ตัวอย่าง:
uint(1) // 1u
dyn ส่งค่าไปยังประเภทแบบไดนามิกเพื่อตรวจสอบประเภท

ลายเซ็น:
dyn(T) -> dyn

ตัวอย่าง:
dyn([1, "two"])
type แสดงผลประเภทของค่า

ลายเซ็น:
type(T) -> type

ตัวอย่าง:
type(1) // int

4. ส่วนขยาย (ไลบรารี)

ไลบรารีการเชื่อมโยง

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
cel.bind เชื่อมโยงตัวแปรภายในเพื่อหลีกเลี่ยงการประเมินที่ซ้ำกัน

ลายเซ็น:
cel.bind(varName, initExpr, resultExpr) -> T

ตัวอย่าง:
cel.bind(x, a + b, x * x)
(v0.15.0) (v0.10.0) (v0.2.0) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Bindings() ไปยัง cel.NewEnv()
  • C++: เพิ่ม BindingsCompilerLibrary() ไปยัง CompilerBuilder (ระบบจะจัดการรันไทม์โดยอัตโนมัติ)
  • Java: เพิ่ม CelExtensions.bindings() ไปยัง CelCompiler และบิลเดอร์ CelRuntime
  • Python: นำเข้า cel_expr_python.ext.ext_bindings และใช้ ExtBindings() ใน cel.NewEnv(extensions=[...])

ไลบรารีโปรแกรมเปลี่ยนไฟล์

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
base64.encode เข้ารหัสไบต์เป็นสตริง Base64

ลายเซ็น:
base64.encode(bytes) -> string

ตัวอย่าง:
base64.encode(b"hello") // "aGVsbG8="
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
base64.decode ถอดรหัสสตริง Base64 เป็นไบต์ แสดงข้อผิดพลาดเมื่อป้อนข้อมูลที่ไม่ถูกต้อง

ลายเซ็น:
base64.decode(string) -> bytes

ตัวอย่าง:
base64.decode("aGVsbG8=") // b"hello"
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
json.encode แปลงค่า CEL เป็นสตริง JSON

ลายเซ็น:
json.encode(dyn) -> string

ตัวอย่าง:
json.encode([1, 2]) // "[1,2]"
(v0.29.0)

วิธีเปิดใช้

  • ไป: ส่ง ext.Encoders() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.encoders() ไปยัง CelCompiler และบิลเดอร์ CelRuntime
  • Python: นำเข้า cel_expr_python.ext.ext_encoders และใช้ ExtEncoders() ใน cel.NewEnv(extensions=[...])

คลังคณิตศาสตร์

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
math.greatest แสดงผลอาร์กิวเมนต์ตัวเลข (หรือรายการตัวเลข) ที่มากที่สุด

ลายเซ็น:
math.greatest(arg, ...) -> T

ตัวอย่าง:
math.greatest(1, 3, 2) // 3
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.least แสดงผลอาร์กิวเมนต์ที่เป็นตัวเลขที่น้อยที่สุด (หรือรายการตัวเลข)

ลายเซ็น:
math.least(arg, ...) -> T

ตัวอย่าง:
math.least([1, 3, 2]) // 1
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.abs ค่าสัมบูรณ์

ลายเซ็น:
math.abs(T) -> T (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.abs(-1) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sqrt รากที่สอง

ลายเซ็น:
math.sqrt(T) -> double (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0`
(v0.25.1) (v0.12.0) (v0.11.0) (v0.1.1)
math.bitAnd บิตแอนด์

ลายเซ็น:
math.bitAnd(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitOr Bitwise OR

ลายเซ็น:
math.bitOr(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitXor บิตไวส์ XOR

ลายเซ็น:
math.bitXor(T, T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitXor(5, 3) // 6`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitNot บิตวายน์ NOT

ลายเซ็น:
math.bitNot(T) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitNot(1) // -2`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftLeft เลื่อนบิตไปทางซ้าย

ลายเซ็น:
math.bitShiftLeft(T, int) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitShiftLeft(1, 2) // 4`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftRight เลื่อนบิตไปทางขวา

ลายเซ็น:
math.bitShiftRight(T, int) -> T (รองรับ int, uint)<br /><br />**Examples:**<br />math.bitShiftRight(4, 2) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.ceil การปัดเศษขึ้น

ลายเซ็น:
math.ceil(double) -> double

ตัวอย่าง:
math.ceil(1.2) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.floor การปัดเศษลง

ลายเซ็น:
math.floor(double) -> double

ตัวอย่าง:
math.floor(1.8) // 1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.round การปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุด

ลายเซ็น:
math.round(double) -> double

ตัวอย่าง:
math.round(1.5) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.trunc การปัดเศษแบบตัดทิ้ง (เข้าหา 0)

ลายเซ็น:
math.trunc(double) -> double

ตัวอย่าง:
math.trunc(-1.8) // -1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isInf ตรวจสอบว่าค่า Double เป็นบวกหรือลบอนันต์

ลายเซ็น:
math.isInf(double) -> bool

ตัวอย่าง:
math.isInf(1.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isNaN ตรวจสอบว่า double เป็น NaN หรือไม่

ลายเซ็น:
math.isNaN(double) -> bool

ตัวอย่าง:
math.isNaN(0.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isFinite ตรวจสอบว่า Double เป็นค่าที่สิ้นสุดหรือไม่

ลายเซ็น:
math.isFinite(double) -> bool

ตัวอย่าง:
math.isFinite(1.2) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sign แสดงเครื่องหมายของค่า (-1, 0 หรือ 1)

ลายเซ็น:
math.sign(T) -> T (รองรับ int, uint, double)<br /><br />**Examples:**<br />math.sign(-42) // -1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Math() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.math() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: นำเข้า cel_expr_python.ext.ext_math และใช้ ExtMath() ใน cel.NewEnv(extensions=[...])

คลัง Protos

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
proto.getExt รับฟิลด์ส่วนขยาย proto2 หรือค่าเริ่มต้นหากไม่ได้ตั้งค่า

ลายเซ็น:
proto.getExt(msg, extName) -> T

ตัวอย่าง:
proto.getExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
proto.hasExt ตรวจสอบว่าได้ตั้งค่าฟิลด์ส่วนขยาย proto2 หรือไม่

ลายเซ็น:
proto.hasExt(msg, extName) -> bool

ตัวอย่าง:
proto.hasExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Protos() ไปยัง cel.NewEnv()
  • C++: เพิ่ม ProtoExtCompilerLibrary() ลงใน CompilerBuilder (ระบบจะจัดการรันไทม์โดยอัตโนมัติ)
  • Java: เพิ่ม CelExtensions.protos() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: นำเข้า cel_expr_python.ext.ext_proto และใช้ ExtProto() ใน cel.NewEnv(extensions=[...])

คลังรายการ

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
distinct แสดงผลองค์ประกอบที่ไม่ซ้ำกัน

ลายเซ็น:
list.distinct() -> list

ตัวอย่าง:
[1, 2, 2].distinct() // [1, 2]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
flatten ทำให้รายการที่ซ้อนกันแบนราบ

ลายเซ็น:
list.flatten([depth]) -> list

ตัวอย่าง:
[[1], [2, 3]].flatten() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.7.1) (v0.1.1)
lists.range แสดงรายการจำนวนเต็ม [0, ..., n-1]

ลายเซ็น:
lists.range(int) -> list(int)

ตัวอย่าง:
lists.range(3) // [0, 1, 2]
(v0.22.0) (v0.11.0) (v0.10.1) (v0.1.1)
reverse กลับรายการ

ลายเซ็น:
list.reverse() -> list

ตัวอย่าง:
[1, 2].reverse() // [2, 1]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
slice รายการย่อยของการคืนสินค้า (รวมจุดเริ่มต้น ไม่รวมจุดสิ้นสุด)

ลายเซ็น:
list.slice(start, end) -> list

ตัวอย่าง:
[1, 2, 3].slice(1, 3) // [2, 3]
(v0.17.0) (v0.11.0) (v0.11.0) (v0.1.1)
sort จัดเรียงรายการองค์ประกอบที่เปรียบเทียบได้

ลายเซ็น:
list.sort() -> list

ตัวอย่าง:
[3, 1, 2].sort() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
sortBy จัดเรียงรายการตามคีย์ที่ประเมินจากนิพจน์

ลายเซ็น:
list.sortBy(var, expr) -> list

ตัวอย่าง:
[{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
first แสดงผลองค์ประกอบแรกเป็นองค์ประกอบที่ไม่บังคับ ต้องใช้ส่วนขยายที่ไม่บังคับ

ลายเซ็น:
list.first() -> optional

ตัวอย่าง:
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)
last แสดงผลองค์ประกอบสุดท้ายเป็นค่าที่ไม่บังคับ ต้องใช้ส่วนขยายที่ไม่บังคับ

ลายเซ็น:
list.last() -> optional

ตัวอย่าง:
[1, 2].last() // optional(2)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)

วิธีเปิดใช้

  • ไป: ส่ง ext.Lists() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.lists() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: เปิดใช้ผ่าน cel.EnvConfig โดยเพิ่ม lists ลงในextensions รายการ

คลังชุด

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
sets.contains ตรวจสอบว่า list1 มีองค์ประกอบทั้งหมดของ list2 หรือไม่

ลายเซ็น:
sets.contains(list1, list2) -> bool

ตัวอย่าง:
sets.contains([1, 2], [1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.equivalent ตรวจสอบว่าลิสต์เทียบเท่ากับชุดหรือไม่ (มีองค์ประกอบที่ไม่ซ้ำกันเหมือนกัน)

ลายเซ็น:
sets.equivalent(list1, list2) -> bool

ตัวอย่าง:
sets.equivalent([1, 2], [2, 1, 1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.intersects ตรวจสอบว่ารายการแชร์องค์ประกอบอย่างน้อย 1 รายการหรือไม่

ลายเซ็น:
sets.intersects(list1, list2) -> bool

ตัวอย่าง:
sets.intersects([1, 2], [2, 3]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Sets() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.sets() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: เปิดใช้ผ่าน cel.EnvConfig โดยเพิ่ม sets ลงในextensions รายการ

คลังสตริง

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
charAt แสดงอักขระที่ดัชนี

ลายเซ็น:
string.charAt(int) -> string

ตัวอย่าง:
"hello".charAt(1) // "e"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
indexOf แสดงดัชนีของสตริงย่อยที่เกิดขึ้นครั้งแรก หรือ -1

ลายเซ็น:
string.indexOf(substr, [start]) -> int

ตัวอย่าง:
"hello".indexOf("l") // 2
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
lastIndexOf แสดงดัชนีของการเกิดสตริงย่อยครั้งสุดท้าย หรือ -1

ลายเซ็น:
string.lastIndexOf(substr, [end]) -> int

ตัวอย่าง:
"hello".lastIndexOf("l") // 3
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
join ต่อสตริง

ลายเซ็น:
list(string).join([separator]) -> string

ตัวอย่าง:
["a", "b"].join("-") // "a-b"
(v0.10.0) (v0.10.0) (v0.2.0) (v0.1.1)
split แยกสตริงตามตัวคั่น

ลายเซ็น:
string.split(separator, [limit]) -> list(string)

ตัวอย่าง:
"a-b".split("-") // ["a", "b"]
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
substring ส่งคืนสตริงย่อย (รวมจุดเริ่มต้น ไม่รวมจุดสิ้นสุด)

ลายเซ็น:
string.substring(start, [end]) -> string

ตัวอย่าง:
"hello".substring(1, 3) // "el"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
trim ตัดช่องว่าง Unicode

ลายเซ็น:
string.trim() -> string

ตัวอย่าง:
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace แทนที่ค่าเก่าด้วยค่าใหม่

รูปแบบ:
string.replace(old, new, [limit]) -> string

ตัวอย่าง:
"hello".replace("l", "w") // "hewwo"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
reverse กลับจุดโค้ด Unicode

ลายเซ็น:
string.reverse() -> string

ตัวอย่าง:
"abc".reverse() // "cba"
(v0.18.0) (v0.14.0) (v0.13.0) (v0.1.1)
lowerAscii แปลงอักขระ ASCII เป็นตัวพิมพ์เล็ก

ลายเซ็น:
string.lowerAscii() -> string

ตัวอย่าง:
"Hello".lowerAscii() // "hello"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
upperAscii แปลงอักขระ ASCII เป็นตัวพิมพ์ใหญ่

ลายเซ็น:
string.upperAscii() -> string

ตัวอย่าง:
"Hello".upperAscii() // "HELLO"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
quote หลีกเลี่ยงสตริงเพื่อการพิมพ์ที่ปลอดภัย

ลายเซ็น:
strings.quote(string) -> string

ตัวอย่าง:
strings.quote("a\tb") // "\"a\\tb\""
(v0.14.0) (v0.14.0) (v0.13.0) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Strings() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.strings() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: นำเข้า cel_expr_python.ext.ext_strings และใช้ ExtStrings() ใน cel.NewEnv(extensions=[...])

คลังนิพจน์ทั่วไป

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
regex.replace แทนที่รายการที่ตรงกันด้วยสตริงการแทนที่ (รองรับการอ้างอิงย้อนกลับ)

รูปแบบ:
regex.replace(target, pat, repl, [limit]) -> string

ตัวอย่าง:
regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123"
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extract แสดงการจับคู่แรกของรูปแบบ (ต้องมีแคปเจอร์กรุ๊ป 1 กลุ่ม)

ลายเซ็น:
regex.extract(target, pat) -> optional(string)

ตัวอย่าง:
regex.extract("a123b", r"(\d+)") // optional("123")
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extractAll แสดงผลการจับคู่ทั้งหมดของรูปแบบ (ต้องมีแคปเจอร์กรุ๊ป 1 กลุ่ม)

ลายเซ็น:
regex.extractAll(target, pat) -> list(string)

ตัวอย่าง:
regex.extractAll("a1b2", r"(\d+)") // ["1", "2"]
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)

วิธีเปิดใช้

  • ไป: ส่ง ext.Regex() ไปยัง cel.NewEnv()
  • C++:
  • Java: เพิ่ม CelExtensions.regex() ไปยัง CelCompiler และ CelRuntime บิลเดอร์
  • Python: เปิดใช้ผ่าน cel.EnvConfig โดยเพิ่ม regex และ optional ลงใน รายการ extensions

การทำความเข้าใจตัวแปร 2 ตัว

มาโคร คำอธิบาย Go C++ Java Python C
all การลัดวงจร AND ตรรกะเหนือคีย์/ดัชนีและค่า

ลายเซ็น:
list.all(i, v, pred) -> bool
map.all(k, v, pred) -> bool

ตัวอย่าง:
[1, 2].all(i, v, v > 0) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
exists การลัดวงจรตรรกะ OR เหนือคีย์/ดัชนีและค่า

ลายเซ็น:
list.exists(i, v, pred) -> bool
map.exists(k, v, pred) -> bool

ตัวอย่าง:
[1, 2].exists(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
existsOne ตรวจสอบว่ามีคู่ที่ตรงตามเพรดิเคตเพียงคู่เดียว

ลายเซ็น:
list.existsOne(i, v, pred) -> bool
map.existsOne(k, v, pred) -> bool

ตัวอย่าง:
[1, 2].existsOne(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformList เปลี่ยน/กรองรายการ/แมปเป็นรายการ

ลายเซ็น:
list.transformList(i, v, [filter], transform) -> list
map.transformList(k, v, [filter], transform) -> list

ตัวอย่าง:
[1, 2].transformList(i, v, v * 2) // [2, 4]
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMap เปลี่ยนค่าของรายการ/แผนที่เป็นแผนที่ (คีย์ยังคงเหมือนเดิม)

ลายเซ็น:
list.transformMap(i, v, [filter], transform) -> map
map.transformMap(k, v, [filter], transform) -> map

ตัวอย่าง:
[1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMapEntry เปลี่ยนเป็นแผนที่

ลายเซ็น:
list.transformMapEntry(i, v, [filter], transform_entry) -> map
map.transformMapEntry(k, v, [filter], transform_entry) -> map

ตัวอย่าง:
[1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)

วิธีเปิดใช้

คลังประเภทเนทีฟ

ฟีเจอร์ คำอธิบาย Go C++ Java Python C
โครงสร้างข้อมูลดั้งเดิม การลงทะเบียนและสร้างอินสแตนซ์ของประเภทดั้งเดิมของโฮสต์ (โครงสร้าง Go / POJO ของ Java) ใน CEL

ตัวอย่าง:
Account{id: 123} (สร้างอินสแตนซ์ POJO ของ Java ใน CEL)
(v0.13.0) (v0.13.0)

วิธีเปิดใช้

  • ไปที่: ส่ง ext.NativeTypes(...) (ระบุประเภทการสะท้อน) ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: เพิ่ม CelExtensions.nativeTypes() (ระบุคลาส Java) ลงในเครื่องมือสร้าง CelCompiler และ CelRuntime
  • Python: ไม่รองรับ

คลังเครือข่าย

ไลบรารีเครือข่ายมีฟังก์ชันสำหรับการแยกวิเคราะห์ ตรวจสอบ และจัดการ ที่อยู่ IP และบล็อก CIDR

ฟังก์ชัน คำอธิบาย Go C++ Java Python C
ip แยกวิเคราะห์สตริงเป็นที่อยู่ IP หรือแยก IP จาก CIDR

ลายเซ็น:
ip(string) -> IP
CIDR.ip() -> IP

ตัวอย่าง:
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP ตรวจสอบว่าสตริงเป็นที่อยู่ IP ที่ถูกต้องหรือไม่

ลายเซ็น:
isIP(string) -> bool

ตัวอย่าง:
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical ตรวจสอบว่าสตริงที่อยู่ IP อยู่ในรูปแบบ Canonical หรือไม่

ลายเซ็น:
ip.isCanonical(string) -> bool

ตัวอย่าง:
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr แยกวิเคราะห์สตริงเป็นบล็อก CIDR

ลายเซ็น:
cidr(string) -> CIDR

ตัวอย่าง:
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR ตรวจสอบว่าสตริงเป็นบล็อก CIDR ที่ถูกต้องหรือไม่

ลายเซ็น:
isCIDR(string) -> bool

ตัวอย่าง:
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP ตรวจสอบว่าบล็อก CIDR มีที่อยู่ IP หรือไม่

ลายเซ็น:
CIDR.containsIP(IP) -> bool
CIDR.containsIP(string) -> bool

ตัวอย่าง:
cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true
(v0.29.0)
containsCIDR ตรวจสอบว่าบล็อก CIDR มีบล็อก CIDR อื่นหรือไม่

ลายเซ็น:
CIDR.containsCIDR(CIDR) -> bool
CIDR.containsCIDR(string) -> bool

ตัวอย่าง:
cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true
(v0.29.0)
family แสดงตระกูล IP (4 สำหรับ IPv4, 6 สำหรับ IPv6)

ลายเซ็น:
IP.family() -> int

ตัวอย่าง:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast ตรวจสอบว่า IP เป็นที่อยู่แบบ Unicast ทั่วโลกหรือไม่

ลายเซ็น:
IP.isGlobalUnicast() -> bool

ตัวอย่าง:
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast ตรวจสอบว่า IP เป็นที่อยู่มัลติคาสต์ลิงก์ภายในหรือไม่

ลายเซ็น:
IP.isLinkLocalMulticast() -> bool

ตัวอย่าง:
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast ตรวจสอบว่า IP เป็นที่อยู่แบบ Unicast ที่ลิงก์ภายในหรือไม่

ลายเซ็น:
IP.isLinkLocalUnicast() -> bool

ตัวอย่าง:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback ตรวจสอบว่า IP เป็นที่อยู่ Loopback หรือไม่

ลายเซ็น:
IP.isLoopback() -> bool

ตัวอย่าง:
ip("127.0.0.1").isLoopback() // true
(v0.29.0)
isMask ตรวจสอบว่า CIDR เป็นซับเน็ตมาสก์ที่ถูกต้องหรือไม่

รูปแบบ:
CIDR.isMask() -> bool

ตัวอย่าง:
cidr("255.255.255.0/24").isMask() // true
(v0.29.0)
isUnspecified ตรวจสอบว่า IP เป็นที่อยู่ที่ไม่ได้ระบุหรือไม่ (เช่น 0.0.0.0)

ลายเซ็น:
IP.isUnspecified() -> bool

ตัวอย่าง:
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked แสดงผลบล็อก CIDR ที่มาสก์

ลายเซ็น:
CIDR.masked() -> CIDR

ตัวอย่าง:
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength แสดงความยาวคำนำหน้าของบล็อก CIDR

ลายเซ็น:
CIDR.prefixLength() -> int

ตัวอย่าง:
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string แปลง IP หรือ CIDR เป็นสตริง

ลายเซ็น:
string(IP) -> string
string(CIDR) -> string

ตัวอย่าง:
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

วิธีเปิดใช้

  • ไป: ส่ง ext.Network() ไปยัง cel.NewEnv()
  • C++: ไม่รองรับ
  • Java: ไม่รองรับ
  • Python: ไม่รองรับ

5. ฟีเจอร์ขั้นสูง

สรุปเกี่ยวกับฟีเจอร์ขั้นสูง

ฟีเจอร์ คำอธิบาย Go C++ Java Python C
การประเมินบางส่วน ประเมินด้วยอินพุตที่ขาดหายไป โดยจะแสดงผลเป็นค่าที่ไม่รู้จักหรือนิพจน์ที่ลดความซับซ้อนแล้ว ³
การประเมินแบบไม่พร้อมกัน การดำเนินการฟังก์ชันส่วนขยายพร้อมกันแบบไม่บล็อก
โปรแกรมตรวจสอบ AST การวิเคราะห์แบบคงที่จะตรวจสอบ AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภท
เครื่องมือเพิ่มประสิทธิภาพ AST การเขียน AST ใหม่ (การพับค่าคงที่ การแทรกอินไลน์ CSE) เพื่อปรับปรุงประสิทธิภาพ
CEL Policy Compiler คอมไพล์โครงสร้างนโยบายที่ใช้ YAML เป็น AST ของ CEL มาตรฐาน

³ Go รองรับการสร้าง Residual AST (AST ที่ตัดแต่งแล้ว) ⁴ C++ และ Java รองรับ การแสดงผล UnknownSet / CelUnknownSet ที่รันไทม์ แต่ไม่ได้เปิดเผย API สาธารณะ สำหรับการสร้าง AST ที่เหลือ ⁵ Go ใช้ AsyncBinding / AsyncOp ที่ส่งคืน แชแนล ⁶ Java ใช้ CelAsyncRuntime ซึ่งแสดงผล ListenableFuture

การประเมินบางส่วน (ไม่ทราบ)

การประเมินบางส่วนช่วยให้ประเมินนิพจน์ได้เมื่อทราบเฉพาะชุดย่อยของตัวแปรอินพุต (อาร์กิวเมนต์) การประเมินจะสร้างผลลัพธ์ที่ระบุสิ่งที่ขาดหายไปหรือนิพจน์ที่ง่ายขึ้นแทนที่จะล้มเหลว

  • ไป: รองรับอย่างเต็มที่ อนุญาตให้กำหนด PartialActivation ด้วยรูปแบบของแอตทริบิวต์ที่ไม่รู้จัก การประเมินจะแสดงผลค่า types.Unknown Go รองรับการสร้าง AST ที่เหลือ (Env.ResidualAst) ซึ่งเป็น AST ที่ตัดทอนและ ลดความซับซ้อนซึ่งมีเฉพาะส่วนของนิพจน์ที่ประเมินค่าไม่ได้
  • C++: รองรับค่า Unknown รูปแบบแอตทริบิวต์ที่ไม่รู้จักจะ กำหนดค่าผ่าน Activation::set_unknown_attribute_patterns การประเมิน จะแสดงผล UnknownSet ขณะนี้ API สาธารณะยังไม่แสดงการสร้าง AST ที่เหลือ
  • Java: รองรับการประเมินบางส่วนผ่าน PartialVars passed to Program.eval() การประเมินจะแสดงผล CelUnknownSet ขณะนี้ Public API ยังไม่แสดงการสร้าง AST ที่เหลือ
  • Python / C: ไม่รองรับโดยตรง

การประเมินแบบไม่พร้อมกัน

การประเมินแบบไม่พร้อมกันช่วยให้นิพจน์ CEL เรียกฟังก์ชันที่ดำเนินการแบบไม่พร้อมกัน (เช่น การเรียก RPC หรือการค้นหาฐานข้อมูล) และบล็อกการประเมินจนกว่าผลลัพธ์จะพร้อมใช้งาน โดยไม่บล็อกเธรดการดำเนินการหลัก

  • Go: รองรับการโอเวอร์โหลดฟังก์ชันแบบอะซิงโครนัสผ่าน AsyncBinding และ AsyncOp ฟังก์ชันแบบไม่พร้อมกันจะแสดงผลแชแนล Go (<-chan ref.Val) และ อินเทอร์พรีเตอร์จะจัดการการดำเนินการพร้อมกันและการซิงโครไนซ์
  • Java: รองรับการประเมินแบบอะซิงโครนัสผ่าน CelAsyncRuntime และ AsyncProgram โดยใช้ ListenableFuture เพื่อแสดงค่าที่รอดำเนินการและ ขับเคลื่อนการประเมินให้เสร็จสมบูรณ์โดยอัตโนมัติเมื่อฟิวเจอร์ได้รับการแก้ไข
  • C++ / Python / C: ไม่รองรับในตัว

โปรแกรมตรวจสอบ AST

เครื่องมือตรวจสอบจะทำการวิเคราะห์แบบคงที่ใน AST ที่ตรวจสอบแล้วหลังจากตรวจสอบประเภทเพื่อ บังคับใช้ข้อจํากัดเฉพาะโดเมนก่อนที่จะมีการเรียกใช้โปรแกรม

  • Go: รองรับอินเทอร์เฟซ ASTValidator เครื่องมือตรวจสอบ Canonical ได้แก่ cel.validator.duration, cel.validator.timestamp, cel.validator.matches (นิพจน์ทั่วไป), cel.validator.homogeneous_literals และ cel.validator.comprehension_nesting_limit
  • C++: รองรับ cel::Validator การตรวจสอบ Canonical ประกอบด้วย AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator และ TimestampLiteralValidator
  • Java: รองรับ CelValidator และ CelAstValidator เครื่องมือตรวจสอบ Canonical ได้แก่ AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidator และ TimestampLiteralValidator
  • Python / C: ไม่มีการสนับสนุนโดยตรง

เครื่องมือเพิ่มประสิทธิภาพ AST

ตัวเพิ่มประสิทธิภาพจะเขียน AST ใหม่เพื่อปรับปรุงประสิทธิภาพการดำเนินการ ตัวเพิ่มประสิทธิภาพแบ่งออกเป็น 2 หมวดหมู่ ได้แก่ ตัวเพิ่มประสิทธิภาพแบบคงที่และตัวเพิ่มประสิทธิภาพรันไทม์ C++, Java และ Go รองรับการเพิ่มประสิทธิภาพรันไทม์ นอกจากนี้ CEL Java และ Go ยังรองรับเครื่องมือเพิ่มประสิทธิภาพแบบคงที่ด้วย การเพิ่มประสิทธิภาพทั่วไป ได้แก่ การพับค่าคงที่ (การประเมินนิพจน์ย่อยล่วงหน้า ด้วยอินพุตค่าคงที่) และการกำจัดนิพจน์ย่อยที่ซ้ำกัน (CSE)

  • Go: รองรับการพับ AST ระหว่างการคอมไพล์/วางแผน
  • C++: รองรับการพับค่าคงที่ผ่านส่วนขยาย cel::extensions::EnableConstantFolding ในเวลาวางแผน
  • Java: รองรับอินเทอร์เฟซ CelOptimizer ตัวเพิ่มประสิทธิภาพ Canonical ได้แก่ ConstantFoldingOptimizer (ซึ่งสามารถพับกิ่งก้านแบบลัดวงจรได้โดย จำลองการประเมินบางส่วน), InliningOptimizer และ SubexpressionOptimizer (CSE)
  • Python / C: ไม่มีการสนับสนุนโดยตรง

เครื่องมือคอมไพล์นโยบาย CEL

นโยบาย CEL เป็นรูปแบบที่อิงตาม YAML สำหรับการเขียนนิพจน์ CEL หลายรายการ ร่วมกับตัวแปร บล็อกการจับคู่ เอาต์พุตแบบมีเงื่อนไข และกฎที่ซ้อนกัน โดยออกแบบมาสำหรับเครื่องมือนโยบายที่ซับซ้อน (เช่น การควบคุมการยอมรับของ Kubernetes) ซึ่งนิพจน์ CEL เดียวจะอ่านไม่ได้

คอมไพเลอร์นโยบายจะคอมไพล์นโยบาย YAML เหล่านี้เป็น AST ของ CEL มาตรฐานรายการเดียว ซึ่งหมายความว่านโยบายเหล่านี้จะเข้ากันได้กับรันไทม์ CEL มาตรฐานอย่างสมบูรณ์และจะรับประกัน ประสิทธิภาพและความปลอดภัยทั้งหมด

  • ไปที่: รองรับผ่าน third_party/cel/go/policy
  • C++: รองรับผ่าน third_party/cel/cpp/policy
  • Java: รองรับผ่าน third_party/java/cel/policy
  • Python / C: ไม่รองรับโดยตรง