このドキュメントは、Common Expression Language(CEL)の統一された API ドキュメント リファレンスとして機能します。すべてのマクロ、演算子、標準関数を一覧表示し、公式の CEL スタック全体でのシグネチャ、動作、サポート ステータスを示します。
言語の動作と仕様の詳細については、CEL 言語の定義をご覧ください。
スタック バージョン
このリファレンス ドキュメントは、次のバージョンの 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 -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> list例: 1 + 2 * 3 // 7[1] + [2] // [1, 2] |
✓ | ✓ | ✓ | ✓ | ✓² |
比較(==、!=、<、<=、>、>=) |
標準の比較。数値の比較は異種です(例: 1 == 1.0)。シグネチャ: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> bool例: x < 42.01 == 1.0 // true |
✓ | ✓ | ✓ | ✓ | ✓ |
論理(!、&&、||、? :) |
論理 NOT、AND、OR、三項条件。短絡評価を使用します。 シグネチャ: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> T例: x > 0 ? "positive" : "non-positive" |
✓ | ✓ | ✓ | ✓ | ✓ |
インデックス登録([]) |
インデックスでリストの要素にアクセスするか、マップでキーを検索します。 シグネチャ: list[int] -> Tmap[K] -> V例: tags[0]users['john'] |
✓ | ✓ | ✓ | ✓ | ✓ |
メンバーシップ(in) |
要素がリストに含まれているか、キーがマップに含まれているかを確認します。 シグネチャ: T in list -> boolK in map -> bool例: 'admin' in roles |
✓ | ✓ | ✓ | ✓ | ✓ |
² リストの連結(list + list)は、他の算術演算子はサポートされているものの、C ランタイムではサポートされていません。
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]) -> intduration.getHours() -> int例: duration("1h30m").getHours() // 1 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes |
分(0 ~ 59)を返します。 シグネチャ: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> int例: duration("1h30m").getMinutes() // 30 |
✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds |
秒(0 ~ 59)を返します。 シグネチャ: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> int例: duration("1h30m45s").getSeconds() // 45 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds |
ミリ秒(0 ~ 999)を返します。 シグネチャ: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> int例: duration("1.5s").getMilliseconds() // 500 |
✓ | ✓ | ✓ | ✓ | ✗ |
型変換
| ターゲット タイプ | 説明 | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
bool |
ブール値に変換します。 シグネチャ: bool(bool) -> boolbool(string) -> bool例: bool("true") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
bytes |
バイトに変換します。 シグネチャ: bytes(bytes) -> bytesbytes(string) -> bytes例: bytes("hello") // b"hello" |
✓ | ✓ | ✓ | ✓ | ✓ |
double |
倍精度浮動小数点数に変換します。 シグネチャ: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> double例: double(1) // 1.0 |
✓ | ✓ | ✓ | ✓ | ✓ |
duration |
期間に変換します。 シグネチャ: duration(duration) -> durationduration(string) -> duration例: duration("1.5s") // 1.5s duration |
✓ | ✓ | ✓ | ✓ | ✓ |
int |
64 ビット符号付き整数に変換します。 シグネチャ: int(int) -> intint(uint) -> intint(double) -> int(ゼロに丸める)int(string) -> intint(timestamp) -> int(エポックからの秒数)例: 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) -> timestamptimestamp(string) -> timestamp(RFC3339)例: timestamp("2026-07-23T00:00:00Z") |
✓ | ✓ | ✓ | ✓ | ✓ |
uint |
64 ビット符号なし整数に変換します。 シグネチャ: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(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:
ext.Bindings()をcel.NewEnv()に渡します。 - C++:
CompilerBuilderにBindingsCompilerLibrary()を追加します。(ランタイムは自動的に処理されます)。 - Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.bindings()を追加します。 - Python:
cel_expr_python.ext.ext_bindingsをインポートし、cel.NewEnv(extensions=[...])でExtBindings()を使用します。
Encoders ライブラリ
| 関数 | 説明 | 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:
ext.Encoders()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにEncodersCompilerLibrary()を追加。 - 実行時:
FunctionRegistryでRegisterEncodersFunctions()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.encoders()を追加します。 - Python:
cel_expr_python.ext.ext_encodersをインポートし、cel.NewEnv(extensions=[...])でExtEncoders()を使用します。
数学ライブラリ
| 関数 | 説明 | 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 |
ビット演算 AND。 シグネチャ: 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 |
ビット演算 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 |
切り捨て丸め(ゼロに向かう方へ)。 シグネチャ: 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) | ✗ |
有効にする方法
- Go:
ext.Math()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにMathCompilerLibrary()を追加。 - 実行時:
FunctionRegistryでRegisterMathExtensionFunctions()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.math()を追加します。 - Python:
cel_expr_python.ext.ext_mathをインポートし、cel.NewEnv(extensions=[...])でExtMath()を使用します。
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) | ✗ |
有効にする方法
- Go:
ext.Protos()をcel.NewEnv()に渡します。 - C++:
CompilerBuilderにProtoExtCompilerLibrary()を追加します。(ランタイムは自動的に処理されます)。 - Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.protos()を追加します。 - 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:
ext.Lists()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにListsCompilerLibrary()を追加。 - ランタイム:
FunctionRegistryでRegisterListsFunctions()を呼び出し、MacroRegistryでRegisterListsMacros()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.lists()を追加します。 - Python:
extensionsリストにlistsを追加して、cel.EnvConfigで有効にします。
セット ライブラリ
| 関数 | 説明 | 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) | ✗ |
有効にする方法
- Go:
ext.Sets()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにSetsCompilerLibrary()を追加。 - 実行時:
FunctionRegistryでRegisterSetsFunctions()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.sets()を追加します。 - Python:
extensionsリストにsetsを追加して、cel.EnvConfigで有効にします。
文字列ライブラリ
| 関数 | 説明 | 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 |
old を new に置き換えます。 シグネチャ: 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:
ext.Strings()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにStringsCompilerLibrary()を追加。 - 実行時:
FunctionRegistryでRegisterStringsFunctions()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.strings()を追加します。 - Python:
cel_expr_python.ext.ext_stringsをインポートし、cel.NewEnv(extensions=[...])でExtStrings()を使用します。
正規表現ライブラリ
| 関数 | 説明 | 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) | ✗ |
有効にする方法
- Go:
ext.Regex()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにRegexExtCompilerLibrary()を追加。 - ランタイム:
FunctionRegistryでRegisterRegexExtensionFunctions()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.regex()を追加します。 - Python:
cel.EnvConfigを介して有効にするには、extensionsリストにregexとoptionalを追加します。
2 変数内包表記
| マクロ | 説明 | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
all |
キー/インデックスと値に対する論理積のショートサーキット。 シグネチャ: list.all(i, v, pred) -> boolmap.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) -> boolmap.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 |
述語を満たすペアが 1 つだけ存在するかどうかを確認します。 シグネチャ: list.existsOne(i, v, pred) -> boolmap.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) -> listmap.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) -> mapmap.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) -> mapmap.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:
ext.TwoVarComprehensions()をcel.NewEnv()に渡します。 - C++:
- コンパイラ:
CompilerBuilderにComprehensionsV2CompilerLibrary()を追加。 - ランタイム:
FunctionRegistryでRegisterComprehensionsV2Functions()を呼び出し、MacroRegistryでRegisterComprehensionsV2Macros()を呼び出します。
- コンパイラ:
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.comprehensions()を追加します。 - Python:
cel.EnvConfigを使用して有効にします。extensionsリストにtwo-var-comprehensionsを追加します。
ネイティブ型ライブラリ
| 機能 | 説明 | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| ネイティブ構造体 | CEL でホスト ネイティブ型(Go 構造体 / Java POJO)を登録してインスタンス化する。 例: Account{id: 123}(CEL でインスタンス化された Java POJO) |
✓(v0.13.0) | ✗ | ✓(v0.13.0) | ✗ | ✗ |
有効にする方法
- Go:
ext.NativeTypes(...)(リフレクション型を提供)をcel.NewEnv()に渡します。 - C++: サポートされていません。
- Java:
CelCompilerビルダーとCelRuntimeビルダーにCelExtensions.nativeTypes()(Java クラスを提供)を追加します。 - Python: サポートされていません。
ネットワーク ライブラリ
Network ライブラリには、IP アドレスと CIDR ブロックの解析、検証、操作を行うための関数が用意されています。
| 関数 | 説明 | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
ip |
文字列を IP アドレスに解析するか、CIDR から IP を抽出します。 シグネチャ: ip(string) -> IPCIDR.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) -> boolCIDR.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) -> boolCIDR.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) -> stringstring(CIDR) -> string例: string(ip("192.168.0.1")) // "192.168.0.1" |
✓(v0.29.0) | ✗ | ✗ | ✗ | ✗ |
有効にする方法
- Go:
ext.Network()をcel.NewEnv()に渡します。 - C++: サポートされていません。
- Java: 対象外です。
- Python: サポートされていません。
5. 高度な機能
高度な機能の概要
| 機能 | 説明 | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| 部分的な評価 | 入力がない状態で評価します。不明な値または簡略化された式を返します。 | ✓³ | ✓⁴ | ✓⁴ | ✗ | ✗ |
| 非同期評価 | 拡張機能関数の非ブロッキング同時実行。 | ✓⁵ | ✗ | ✓⁶ | ✗ | ✗ |
| AST 検証ツール | 型チェック後の Checked AST に対する静的分析チェック。 | ✓ | ✓ | ✓ | ✗ | ✗ |
| AST オプティマイザー | パフォーマンスを改善するための AST の書き換え(定数畳み込み、インライン化、CSE)。 | ✓ | ✓ | ✓ | ✗ | ✗ |
| CEL ポリシー コンパイラ | YAML ベースのポリシー構造を標準の CEL AST にコンパイルします。 | ✓ | ✓ | ✓ | ✗ | ✗ |
³ Go は、残余 AST(プルーニングされた AST)の生成をサポートしています。⁴ C++ と Java は、実行時に UnknownSet / CelUnknownSet を返すことをサポートしていますが、残りの AST 生成用の公開 API は公開していません。⁵ Go は AsyncBinding / AsyncOp を使用してチャネルを返します。⁶ Java では CelAsyncRuntime を使用し、ListenableFuture を返します。
部分評価(不明)
部分評価では、入力変数(引数)のサブセットのみがわかっている場合に式を評価できます。評価は失敗するのではなく、何が欠落しているかを示す結果または簡略化された式を生成します。
- Go: フルサポート。不明な属性のパターンで
PartialActivationを定義できます。評価はtypes.Unknown値を返します。Go は、評価できなかった式の部分のみを含む、プルーニングされ簡略化された AST である残余 AST(Env.ResidualAst)の生成をサポートしています。 - C++:
Unknown値をサポートします。不明な属性パターンはActivation::set_unknown_attribute_patternsを介して構成されます。評価はUnknownSetを返します。現在、公開 API では残余 AST の生成は公開されていません。 - Java:
Program.eval()に渡されたPartialVarsを介して部分評価をサポートします。評価はCelUnknownSetを返します。現在、公開 API は残差 AST 生成を公開していません。 - Python / C: ネイティブ サポートはありません。
非同期評価
非同期評価を使用すると、CEL 式で非同期で実行される関数(RPC やデータベース クエリの作成など)を呼び出し、メイン実行スレッドをブロックすることなく、結果が利用可能になるまで評価をブロックできます。
- Go:
AsyncBindingとAsyncOpを介して非同期関数オーバーロードをサポートします。非同期関数は Go チャネル(<-chan ref.Val)を返し、インタープリタは同時実行と同期を管理します。 - Java:
CelAsyncRuntimeとAsyncProgramによる非同期評価をサポートします。ListenableFutureを使用して保留中の値を表し、フューチャーが解決されると評価を自動的に完了させます。 - C++ / Python / C: 組み込みサポートはありません。
AST バリデータ
検証ツールは、型チェック後に Checked AST に対して静的分析を行い、プログラムが実行される前にドメイン固有の制約を適用します。
- Go:
ASTValidatorインターフェースをサポートします。正規の検証ツールには、cel.validator.duration、cel.validator.timestamp、cel.validator.matches(正規表現)、cel.validator.homogeneous_literals、cel.validator.comprehension_nesting_limitがあります。 - C++:
cel::Validatorをサポートします。正規の検証には、AstDepthValidator、ComprehensionNestingLimitValidator、DurationLiteralValidator、HomogeneousLiteralValidator、MatchesValidator、TimestampLiteralValidatorが含まれます。 - Java:
CelValidatorとCelAstValidatorをサポートします。標準の検証ツールには、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インターフェースをサポートします。標準オプティマイザーには、ConstantFoldingOptimizer(部分評価をシミュレートして短絡分岐を折りたたむことができます)、InliningOptimizer、SubexpressionOptimizer(CSE)などがあります。 - Python / C: 直接のサポートはありません。
CEL ポリシー コンパイラ
CEL ポリシーは、複数の CEL 式を、変数、一致ブロック、条件付き出力、ネストされたルールとともに構成するための YAML ベースの形式です。これは、単一の CEL 式が読みにくくなる複雑なポリシー エンジン(Kubernetes Admission Control など)向けに設計されています。
ポリシー コンパイラは、これらの YAML ポリシーを単一の標準 CEL AST にコンパイルします。つまり、標準の CEL ランタイムと完全に互換性があり、パフォーマンスと安全性の保証をすべて継承します。
- Go:
third_party/cel/go/policyでサポートされています。 - C++:
third_party/cel/cpp/policyを介してサポートされます。 - Java:
third_party/java/cel/policyでサポートされています。 - Python / C: 直接サポートされていません。