一般運算語言 (CEL) API 參考資料

本文件是通用運算式語言 (CEL) 的統一 API 文件參考資料。這份清單列出所有巨集、運算子和標準函式,並指出其簽章、行為和支援狀態 (適用於官方 CEL 堆疊)。

如要進一步瞭解語言行為和規格,請參閱 CEL 語言定義

堆疊版本

本參考文件是以下列版本的 CEL 堆疊為基礎:

  • CEL Gov0.29.2 (和更新版本)
  • CEL C++v0.15.0
  • CEL Javav0.13.1
  • CEL Pythonv0.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) 測試清單中是否至少有一個元素符合述詞。

簽章:
list.exists(var, predicate) -> bool

範例:
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) 測試清單中是否只有一個項目符合述詞。

簽章:
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)。Go、C++、Java 和 Python 支援清單串連 (list + list)。

簽章:
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
邏輯 (!&&||? :) 邏輯 NOT、AND、OR 和三元條件。AND/OR 使用短路求值。

簽章:
!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 (其中 Tstringbyteslistmap)<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.Timestampgoogle.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 (四捨五入至零)
int(string) -> int
int(timestamp) -> int (自 Epoch 以來的秒數)

範例:
int(1.5) // 1
string 轉換為字串。

簽章:
string(T) -> string (支援 boolintuintdoublebytestimestampduration)<br /><br />**Examples:**<br />string(1.5) // "1.5"`
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)

如何啟用

編碼器程式庫

函式 說明 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)

如何啟用

數學程式庫

函式 說明 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 (支援 intuintdouble)<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 (支援 intuintdouble)<br /><br />**Examples:**<br />math.sqrt(9) // 3.0`
(v0.25.1) (v0.12.0) (v0.11.0) (v0.1.1)
math.bitAnd 位元 AND。

簽章:
math.bitAnd(T, T) -> T (支援 intuint)<br /><br />**Examples:**<br />math.bitAnd(5, 3) // 1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitOr 位元 OR。

簽章:
math.bitOr(T, T) -> T (支援 intuint)<br /><br />**Examples:**<br />math.bitOr(5, 3) // 7`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitXor 位元互斥或。

簽章:
math.bitXor(T, T) -> T (支援 intuint)<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 (支援 intuint)<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 (支援 intuint)<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 (支援 intuint)<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 截斷捨去 (趨近於零)。

簽章:
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 (支援 intuintdouble)<br /><br />**Examples:**<br />math.sign(-42) // -1`
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

如何啟用

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() 新增至 CelCompilerCelRuntime 建構工具。
  • Python:匯入 cel_expr_python.ext.ext_proto 並在 cel.NewEnv(extensions=[...]) 中使用 ExtProto()

清單庫

函式 說明 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)

如何啟用

集合庫

函式 說明 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 檢查清單是否共用至少一個元素。

簽章:
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() 新增至 CelCompilerCelRuntime 建構工具。
  • Python:透過 cel.EnvConfig 啟用,方法是將 sets 新增至 extensions 清單。

字串庫

函式 說明 Go C++ Java Python C
charAt 傳回索引處的字元。

簽章:
string.charAt(int) -> string

範例:
"hello".charAt(1) // "e"
(第 0.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)

如何啟用

規則運算式程式庫

函式 說明 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 傳回模式的第一個相符項目 (必須有一個擷取群組)。

簽章:
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 傳回模式的所有相符項目 (必須有一個擷取群組)。

簽章:
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)

如何啟用

雙變數理解

巨集 說明 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
原生結構體 在 CEL 中註冊及例項化主機原生型別 (Go 結構體 / Java POJO)。

範例:
Account{id: 123} (在 CEL 中例項化的 Java POJO)
(v0.13.0) (v0.13.0)

如何啟用

網路程式庫

Network 程式庫提供函式,可剖析、驗證及操控 IP 位址和 CIDR 區塊。

函式 說明 Go C++ Java Python C
ip 將字串剖析為 IP 位址,或從 CIDR 擷取 IP。

簽章:
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 位址字串是否為標準格式。

簽章:
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 系列 (IPv4 為 4,IPv6 為 6)。

簽章:
IP.family() -> int

示例:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast 檢查 IP 是否為全域單點播送位址。

簽章:
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 是否為連結本機單點播送位址。

簽章:
IP.isLinkLocalUnicast() -> bool

範例:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback 檢查 IP 是否為迴路位址。

簽章:
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 政策編譯器 將以 YAML 為基礎的政策結構編譯為標準 CEL AST。

³ Go 支援產生剩餘 AST (修剪後的 AST)。⁴ C++ 和 Java 支援在執行階段傳回 UnknownSet / CelUnknownSet,但不公開用於產生剩餘 AST 的 API。⁵ Go 會使用 AsyncBinding / AsyncOp 傳回管道。⁶ Java 會使用回傳 ListenableFutureCelAsyncRuntime

部分評估 (不明)

如果只知道部分輸入變數 (引數),即可使用部分評估功能評估運算式。評估作業不會失敗,而是會產生結果,指出缺少什麼內容或簡化運算式。

  • 前往:完整支援。可定義具有未知屬性模式的 PartialActivation。評估會傳回 types.Unknown 值。Go 支援產生剩餘 AST (Env.ResidualAst),這是經過修剪的簡化 AST,只包含無法評估的運算式部分。
  • C++:支援 Unknown 值。不明屬性模式是透過 Activation::set_unknown_attribute_patterns 設定。評估 會傳回 UnknownSet。公用 API 目前不會公開剩餘的 AST 生成量。
  • Java:支援透過傳遞至 Program.eval()PartialVars 進行部分評估。評估會傳回 CelUnknownSet。公用 API 目前不會公開剩餘的 AST 生成作業。
  • Python / C:不支援原生功能。

非同步評估

非同步評估功能可讓 CEL 運算式呼叫非同步執行的函式 (例如發出 RPC 或資料庫查詢),並封鎖評估作業,直到結果可用為止,但不會封鎖主要執行緒。

  • Go:透過 AsyncBindingAsyncOp 支援非同步函式多載。非同步函式會傳回 Go 管道 (<-chan ref.Val),而解譯器會管理並行執行和同步處理。
  • Java:透過 CelAsyncRuntimeAsyncProgram 支援非同步評估。它會使用 ListenableFuture 代表待處理的值,並在 Future 解決時自動完成評估。
  • C++ / Python / C:不支援內建功能。

AST 驗證工具

驗證器會在型別檢查後對 Checked AST 執行靜態分析,以強制執行網域專屬限制,然後再執行程式。

  • Go:支援 ASTValidator 介面。標準驗證器包括 cel.validator.durationcel.validator.timestampcel.validator.matches (規則運算式)、cel.validator.homogeneous_literalscel.validator.comprehension_nesting_limit
  • C++:支援 cel::Validator。標準驗證包括 AstDepthValidatorComprehensionNestingLimitValidatorDurationLiteralValidatorHomogeneousLiteralValidatorMatchesValidatorTimestampLiteralValidator
  • Java:支援 CelValidatorCelAstValidator。標準驗證器包括 AstDepthLimitValidatorComprehensionNestingLimitValidatorDurationLiteralValidatorHomogeneousLiteralValidatorRegexLiteralValidatorTimestampLiteralValidator
  • Python / C:不直接支援。

AST Optimizers

最佳化工具會重新編寫 AST,以提升執行效能。最佳化工具可分為兩類:靜態和執行階段最佳化工具。C++、Java 和 Go 支援執行階段最佳化。CEL Java 和 Go 也支援靜態最佳化工具。 常見的最佳化包括常數摺疊 (使用常數輸入預先評估子運算式) 和常見子運算式消除 (CSE)。

  • Go:在編譯/規劃期間支援 AST 折疊。
  • C++:在規劃期間,透過 cel::extensions::EnableConstantFolding 擴充功能支援常數摺疊。
  • Java:支援 CelOptimizer 介面。標準最佳化工具包括 ConstantFoldingOptimizer (可透過模擬部分評估來摺疊短路分支)、InliningOptimizerSubexpressionOptimizer (CSE)。
  • Python / C:不直接支援。

CEL 政策編譯器

CEL 政策是以 YAML 為基礎的格式,可將多個 CEL 運算式與變數、比對區塊、條件式輸出內容和巢狀規則組合在一起。這項功能適用於複雜的政策引擎 (例如 Kubernetes 准入控制),因為單一 CEL 運算式會變得難以解讀。

政策編譯器會將這些 YAML 政策編譯為單一標準 CEL AST,代表這些政策完全相容於標準 CEL 執行階段,並會繼承所有效能和安全保障。

  • 前往:支援頁面 (透過 third_party/cel/go/policy)。
  • C++:透過 third_party/cel/cpp/policy 支援。
  • Java:透過 third_party/java/cel/policy 支援。
  • Python / C:不直接支援。